Compare commits

..

14 commits

Author SHA1 Message Date
Helge Heß
abd05af347 Add SPM sample to README
...
2020-04-10 19:05:28 +02:00
Helge Heß
dc1b0d9c54 Put public kit headers to own dir for SPM
SPM expects the public headers dir to only have a single
directory. Which is why we can't use "xcode" as the pubdir
header.
We also can't use OLMKit as the dir, because then imports
will fail due to "<OLMKit/" not being available.
2020-04-10 18:55:37 +02:00
Helge Heß
a22cffdd29 Separate C from C++ headers for SPM
Swift can't import C++, so we need to remove it from
the module.
2020-04-10 18:50:34 +02:00
Helge Heß
c31a2f2f39 Add crypto algos from lib to libolm target
Have been linking libolm only.
2020-04-10 18:34:51 +02:00
Helge Heß
8e35ea320c Ignore Xcode .swiftpm in .gitignore
Useless noize.
2020-04-10 18:32:27 +02:00
Helge Heß
4c51a48aa7 Add SPM test target, rename tests to .mm for C++
Doesn't link yet though, need to check why.
2020-04-10 18:26:43 +02:00
Helge Heß
4f2f851762 Exclude Info.plist from SPM compilation
Otherwise this shows a warning.
2020-04-10 18:15:39 +02:00
Helge Heß
84d33563c5 Use proper format specifier for uint_8 values
%hhu, as suggested by Xcode.
2020-04-10 18:13:24 +02:00
Helge Heß
f4ab61fa46 Add remaining explicit C++ void casts necessary
OLMKit now compiles fine.
2020-04-10 18:12:30 +02:00
Helge Heß
29d3bc749b
Add OLMKit target to SPM manifest
OLMKit doesn't compile yet, but we are getting closer.
2020-04-10 17:27:56 +02:00
Helge Heß
8deccb9c51
Add explicit C++ casts when assigning from void*
C++ requires explicit casts when assign void * return
types like from `malloc`, to a more specific pointer.
2020-04-10 17:26:34 +02:00
Helge Heß
1e5910a681
Properly mark ObjC++ files as such by using .mm
.m is plain Objective-C and can't import C++ headers
as provided by libolm.
2020-04-10 17:13:32 +02:00
Helge Heß
f3faaba3e7
Add a Swift Package Manager manifest
This one only builds libolm, not yet the Xcode stuff.
2020-04-10 17:09:15 +02:00
Helge Heß
24d33957ed
Add SPM .build directory to .gitignore
We don't need SPM build artifacts in the repository.
2020-04-10 17:04:17 +02:00
500 changed files with 5984 additions and 47002 deletions

View file

@ -1,14 +0,0 @@
root = true
[*]
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf
[*.{c,cpp,h,hh,py,ts,js,java,m}]
indent_style = space
indent_size = 4
[Makefile]
indent_style = tab

17
.gitignore vendored
View file

@ -6,20 +6,9 @@
/olm-*.tgz /olm-*.tgz
/README.html /README.html
/tracing/README.html /tracing/README.html
/python/dist
/javascript/checksums.txt
/javascript/checksums.txt.asc
/javascript/olm_prefix.js
/compile_commands.json
/.clang-format
.ccls-cache/
/python/.eggs
/python/install-temp
/result
# Xcode # Xcode
build/ build/
.build/
DerivedData/ DerivedData/
*.pbxuser *.pbxuser
!default.pbxuser !default.pbxuser
@ -39,5 +28,7 @@ xcuserdata/
Pods/ Pods/
*.xcworkspace *.xcworkspace
# JetBrains tools # Swift Package Manager
.idea/ .build
.swiftpm

View file

@ -1,51 +0,0 @@
default:
image: registry.fedoraproject.org/fedora-minimal:latest
stages:
- build
- test
- trigger
build:lib:
stage: build
tags:
- docker
script:
- microdnf --assumeyes --nodocs install cmake gcc gcc-c++
- cmake . -Bbuild
- cmake --build build
artifacts:
paths:
- build/
test:lib:
stage: test
tags:
- docker
needs:
- build:lib
script:
- microdnf --assumeyes --nodocs install cmake
- pushd build/tests
- ctest .
artifacts:
paths:
- build/tests/Testing/Temporary/
trigger:android:
stage: trigger
trigger:
strategy: depend
include: android/.gitlab-ci.yml
trigger:javascript:
stage: trigger
trigger:
strategy: depend
include: javascript/.gitlab-ci.yml
trigger:python:
stage: trigger
trigger:
strategy: depend
include: python/.gitlab-ci.yml

View file

@ -1,197 +1,7 @@
Changes in `3.2.16 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.16>`_
===========================================================================
This release includes the following changes since 3.2.15:
* Fix and modernize the Python packaging (thanks to Alfred Wingate)
Changes in `3.2.15 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.15>`_
===========================================================================
This release includes the following changes since 3.2.14:
* Improvements to Python packaging
* No longer depend on ``future`` since Python 2 is no longer supported.
* Improve compatibility with tox 4.
* Add support for making standalone sdist.
* Improvements to Nix flake (Thanks to Jon Ringer)
* Improve structure.
* Enable Darwin builds.
* Typescript type fix.
Changes in `3.2.14 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.14>`_
===========================================================================
This release includes the following changes since 3.2.13:
* TypeScript type improvements.
* Improvements to Python packaging
* Documentation improvements.
Changes in `3.2.13 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.13>`_
===========================================================================
This release includes the following changes since 3.2.12:
* Fix compilation with newer versions of emscripten.
* The npm package is compiled with emscripten 3.1.17 to fix compatibility with
node 18.
* Add py.typed to Python wheels.
* Some documentation fixes and updates.
* Improve the pkgconfig file.
Changes in `3.2.12 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.12>`_
===========================================================================
This release includes the following changes since 3.2.11:
* Expose olm_sas_calculate_mac_fixed_base64 in the bindings.
* Allow memory to grow in wasm. Thanks to benkuly for the suggestion.
* Fix Python type hints.
* Some Python build fixes.
* Initial work on a Nix flake for building and testing.
Changes in `3.2.11 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.11>`_
===========================================================================
This release includes the following changes since 3.2.10:
* Fix building documentation. Thanks to Jonas Smedegaard. The documents
written in Markdown are now converted to HTML using Pandoc.
* Add methods for getting unpublished fallback key in Objective-C binding.
* Add public pickle/unpickle methods to Java binding.
* Add wrapper for olm_session_describe to Java binding. Thanks to Alex Baker.
Changes in `3.2.10 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.10>`_
===========================================================================
This release includes no change since 3.2.9, but is created to be able to
publish again the Android library on MavenCentral.
Changes in `3.2.9 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.9>`_
=========================================================================
This release includes the following changes since 3.2.8:
* Switch C++ tests to use doctest. Thanks to Nicolas Werner.
* Switch JavaScript tests to use jasmine instead of deprecated jasmine-node.
* Add session describe function to Python binding. Thanks to Tulir Asokan.
Changes in `3.2.8 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.8>`_
=========================================================================
This release includes the following changes since 3.2.7:
* Improve handling of olm_session_describe when the buffer is too small.
* Ensure random arrays are blanked in JavaScript bindings.
Changes in `3.2.7 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.7>`_
=========================================================================
This release includes the following changes since 3.2.6:
* Fix installation with the Makefile.
* Fix exporting again, so we only export olm symbols.
* Fix WASM build. Thanks to Benjamin Kampmann.
* Add more functions for fallback keys.
Changes in `3.2.6 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.6>`_
=========================================================================
This release includes the following changes since 3.2.5:
* Fix building on various platforms when using CMake. Building from the
Makefile still assumes that it is using gcc.
Changes in `3.2.5 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.5>`_
=========================================================================
This release includes the following changes since 3.2.4:
* Add functions for getting error codes rather than error strings. Thanks to
Nicolas Werner for the suggestion.
* Only export olm symbols. Thanks to Mohammed Sadiq for the suggestion.
* Improve error handling in unpickle functions.
* Add support for fallback keys to the Objective-C and Android bindings.
Changes in `3.2.4 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.4>`_
=========================================================================
This release includes the following changes since 3.2.3:
* Android build fixes.
Changes in `3.2.3 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.3>`_
=========================================================================
This release includes the following changes since 3.2.2:
* Add some checks for invalid input and ensure all fields are initialized.
* Include LibreJS license tags. Thanks to Johannes Marbach for the suggestion.
* Support for Swift Package Manager. Thanks to Johannes Marbach.
Changes in `3.2.2 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.2>`_
=========================================================================
This release includes the following changes since 3.2.1:
* Fixes in the TypeScript definition file.
* CMake build fixes. Thanks to Gorgurov Alexey.
* Change the JavaScript package name to ``@matrix-org/olm``. Note that
this means that packages will need to change their ``require`` or
``import`` statements to use this new name.
* Include file checksums in the JavaScript package.
* Fix length calculation in fallback key json. Thanks to Tobias Furuholm.
* Add a new function to calculate the correct base64 encoding for SAS.
(Currently only available in the C API.)
* Add the ability to specify a pickle key in the Objective-C binding.
* Add pkg-config file on Unix-like systems.
Changes in `3.2.1 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.1>`_
=========================================================================
This release includes the following changes since 3.2.0:
* Fixes in the TypeScript definition file.
Changes in `3.2.0 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.0>`_
=========================================================================
This release includes the following changes since 3.1.5:
* Add support for fallback keys (MSC2732).
* Allow some arguments in the JavaScript bindings to be either Uint8Array or
strings.
* Fixes to the TypeScript definition file.
* Improvements to the JavaScript group demo. Thanks to Saúl Ibarra Corretgé.
* Ensure that the other party's public key has been set in SAS module. Thanks
to Saúl Ibarra Corretgé.
* Fix building with newer versions of emscripten, and simplify makefile. Thanks
to Lukas Lihotzki.
* Reduce pollution of the global namespace in the Javascript binding. Thanks to
Lukas Lihotzki.
Changes in `3.1.5 <https://gitlab.matrix.org/matrix-org/olm/tags/3.1.5>`_
=========================================================================
This release includes the following changes since 3.1.4:
* Build improvements:
* Fix CMake handling when installing in a non-standard location. Thanks to
Alexey Rusakov.
* Add support in the Makefile for creating a WASM-ready archive. Thanks to
stoically.
* Improve support for LLVM is Makefile. Thanks to caywin25 for reporting.
* Add a TypeScript definition file.
* Some documentation and example fixes.
* Add list of bindings to the README.
Changes in `3.1.4 <https://gitlab.matrix.org/matrix-org/olm/tags/3.1.4>`_ Changes in `3.1.4 <https://gitlab.matrix.org/matrix-org/olm/tags/3.1.4>`_
========================================================================= =========================================================================
This release includes the following changes since 3.1.3: This release includes the following changes since 3.1.4:
* Build improvements: * Build improvements:
* Install headers in the system-configured include directory with CMake. * Install headers in the system-configured include directory with CMake.

View file

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.4) cmake_minimum_required(VERSION 3.4)
project(olm VERSION 3.2.16 LANGUAGES CXX C) project(olm VERSION 3.1.4 LANGUAGES CXX C)
option(OLM_TESTS "Build tests" ON) option(OLM_TESTS "Build tests" ON)
option(BUILD_SHARED_LIBS "Build as a shared library" ON) option(BUILD_SHARED_LIBS "Build as a shared library" ON)
@ -21,10 +21,6 @@ if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release) set(CMAKE_BUILD_TYPE Release)
endif() endif()
set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
add_library(olm add_library(olm
src/account.cpp src/account.cpp
src/base64.cpp src/base64.cpp
@ -52,11 +48,6 @@ add_library(olm
lib/curve25519-donna/curve25519-donna.c) lib/curve25519-donna/curve25519-donna.c)
add_library(Olm::Olm ALIAS olm) add_library(Olm::Olm ALIAS olm)
# restrict the exported symbols
include(GenerateExportHeader)
generate_export_header(olm
EXPORT_FILE_NAME ${CMAKE_CURRENT_SOURCE_DIR}/include/olm/olm_export.h)
target_include_directories(olm target_include_directories(olm
PUBLIC PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
@ -69,18 +60,14 @@ set_target_properties(olm PROPERTIES
VERSION ${PROJECT_VERSION}) VERSION ${PROJECT_VERSION})
set_target_properties(olm PROPERTIES set_target_properties(olm PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
include(GNUInstallDirs)
# Make a pkg-config file
configure_file(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY NEWLINE_STYLE UNIX)
# #
# Installation # Installation
# #
include(GNUInstallDirs)
set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/Olm) set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/Olm)
install(TARGETS olm install(TARGETS olm
EXPORT olm-targets EXPORT olm-targets
@ -92,21 +79,13 @@ install(TARGETS olm
# The exported target will be named Olm. # The exported target will be named Olm.
set_target_properties(olm PROPERTIES EXPORT_NAME Olm) set_target_properties(olm PROPERTIES EXPORT_NAME Olm)
install(FILES install(FILES
${CMAKE_CURRENT_SOURCE_DIR}/include/olm/olm.h ${CMAKE_SOURCE_DIR}/include/olm/olm.h
${CMAKE_CURRENT_SOURCE_DIR}/include/olm/olm_export.h ${CMAKE_SOURCE_DIR}/include/olm/outbound_group_session.h
${CMAKE_CURRENT_SOURCE_DIR}/include/olm/outbound_group_session.h ${CMAKE_SOURCE_DIR}/include/olm/inbound_group_session.h
${CMAKE_CURRENT_SOURCE_DIR}/include/olm/inbound_group_session.h ${CMAKE_SOURCE_DIR}/include/olm/pk.h
${CMAKE_CURRENT_SOURCE_DIR}/include/olm/pk.h ${CMAKE_SOURCE_DIR}/include/olm/sas.h
${CMAKE_CURRENT_SOURCE_DIR}/include/olm/sas.h
${CMAKE_CURRENT_SOURCE_DIR}/include/olm/error.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/olm) DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/olm)
if (UNIX AND NOT APPLE)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
)
endif ()
# Export the targets to a script. # Export the targets to a script.
install(EXPORT olm-targets install(EXPORT olm-targets
FILE OlmTargets.cmake FILE OlmTargets.cmake

191
Makefile
View file

@ -4,12 +4,14 @@ include common.mk
VERSION := $(MAJOR).$(MINOR).$(PATCH) VERSION := $(MAJOR).$(MINOR).$(PATCH)
PREFIX ?= /usr/local PREFIX ?= /usr/local
BUILD_DIR := build BUILD_DIR := build
RELEASE_OPTIMIZE_FLAGS ?= -O3 RELEASE_OPTIMIZE_FLAGS ?= -g -O3
DEBUG_OPTIMIZE_FLAGS ?= -g -O0 -U_FORTIFY_SOURCE DEBUG_OPTIMIZE_FLAGS ?= -g -O0
JS_OPTIMIZE_FLAGS ?= -O3 JS_OPTIMIZE_FLAGS ?= -O3
FUZZER_OPTIMIZE_FLAGS ?= -O3 FUZZING_OPTIMIZE_FLAGS ?= -O3
CC = gcc
EMCC = emcc EMCC = emcc
EMAR = emar AFL_CC = afl-gcc
AFL_CXX = afl-g++
AR = ar AR = ar
UNAME := $(shell uname) UNAME := $(shell uname)
@ -27,36 +29,29 @@ STATIC_RELEASE_TARGET := $(BUILD_DIR)/libolm.a
DEBUG_TARGET := $(BUILD_DIR)/libolm_debug.$(SO).$(VERSION) DEBUG_TARGET := $(BUILD_DIR)/libolm_debug.$(SO).$(VERSION)
JS_WASM_TARGET := javascript/olm.js JS_WASM_TARGET := javascript/olm.js
JS_ASMJS_TARGET := javascript/olm_legacy.js JS_ASMJS_TARGET := javascript/olm_legacy.js
WASM_TARGET := $(BUILD_DIR)/wasm/libolm.a
JS_EXPORTED_FUNCTIONS := javascript/exported_functions.json JS_EXPORTED_FUNCTIONS := javascript/exported_functions.json
JS_EXPORTED_RUNTIME_METHODS := [ALLOC_STACK,writeAsciiToMemory,intArrayFromString,UTF8ToString,stringToUTF8] JS_EXTRA_EXPORTED_RUNTIME_METHODS := ALLOC_STACK
JS_EXTERNS := javascript/externs.js JS_EXTERNS := javascript/externs.js
PUBLIC_HEADERS := include/olm/olm.h include/olm/outbound_group_session.h include/olm/inbound_group_session.h include/olm/pk.h include/olm/sas.h include/olm/error.h include/olm/olm_export.h PUBLIC_HEADERS := include/olm/olm.h include/olm/outbound_group_session.h include/olm/inbound_group_session.h include/olm/pk.h include/olm/sas.h
SOURCES := $(wildcard src/*.cpp) $(wildcard src/*.c) \ SOURCES := $(wildcard src/*.cpp) $(wildcard src/*.c) \
lib/crypto-algorithms/sha256.c \ lib/crypto-algorithms/sha256.c \
lib/crypto-algorithms/aes.c \ lib/crypto-algorithms/aes.c \
lib/curve25519-donna/curve25519-donna.c lib/curve25519-donna/curve25519-donna.c
FUZZER_SOURCES := $(wildcard fuzzing/fuzzers/fuzz_*.cpp) $(wildcard fuzzing/fuzzers/fuzz_*.c) FUZZER_SOURCES := $(wildcard fuzzers/fuzz_*.cpp) $(wildcard fuzzers/fuzz_*.c)
TEST_SOURCES := $(wildcard tests/test_*.cpp) $(wildcard tests/test_*.c) TEST_SOURCES := $(wildcard tests/test_*.cpp) $(wildcard tests/test_*.c)
OBJECTS := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCES))) OBJECTS := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCES)))
RELEASE_OBJECTS := $(addprefix $(BUILD_DIR)/release/,$(OBJECTS)) RELEASE_OBJECTS := $(addprefix $(BUILD_DIR)/release/,$(OBJECTS))
DEBUG_OBJECTS := $(addprefix $(BUILD_DIR)/debug/,$(OBJECTS)) DEBUG_OBJECTS := $(addprefix $(BUILD_DIR)/debug/,$(OBJECTS))
FUZZER_OBJECTS := $(addprefix $(BUILD_DIR)/fuzzers/objects/,$(OBJECTS)) FUZZER_OBJECTS := $(addprefix $(BUILD_DIR)/fuzzers/objects/,$(OBJECTS))
FUZZER_ASAN_OBJECTS := $(addprefix $(BUILD_DIR)/fuzzers/objects/,$(addprefix asan_,$(OBJECTS))) FUZZER_BINARIES := $(addprefix $(BUILD_DIR)/,$(basename $(FUZZER_SOURCES)))
FUZZER_MSAN_OBJECTS := $(addprefix $(BUILD_DIR)/fuzzers/objects/,$(addprefix msan_,$(OBJECTS)))
FUZZER_DEBUG_OBJECTS := $(addprefix $(BUILD_DIR)/fuzzers/objects/,$(addprefix debug_,$(OBJECTS)))
FUZZER_BINARIES := $(addprefix $(BUILD_DIR)/fuzzers/,$(basename $(notdir $(FUZZER_SOURCES))))
FUZZER_ASAN_BINARIES := $(addsuffix _asan,$(FUZZER_BINARIES))
FUZZER_MSAN_BINARIES := $(addsuffix _msan,$(FUZZER_BINARIES))
FUZZER_DEBUG_BINARIES := $(patsubst $(BUILD_DIR)/fuzzers/fuzz_%,$(BUILD_DIR)/fuzzers/debug_%,$(FUZZER_BINARIES)) FUZZER_DEBUG_BINARIES := $(patsubst $(BUILD_DIR)/fuzzers/fuzz_%,$(BUILD_DIR)/fuzzers/debug_%,$(FUZZER_BINARIES))
TEST_BINARIES := $(patsubst tests/%,$(BUILD_DIR)/tests/%,$(basename $(TEST_SOURCES))) TEST_BINARIES := $(patsubst tests/%,$(BUILD_DIR)/tests/%,$(basename $(TEST_SOURCES)))
JS_OBJECTS := $(addprefix $(BUILD_DIR)/javascript/,$(OBJECTS)) JS_OBJECTS := $(addprefix $(BUILD_DIR)/javascript/,$(OBJECTS))
WASM_OBJECTS := $(addprefix $(BUILD_DIR)/wasm/,$(OBJECTS))
# pre & post are the js-pre/js-post options to emcc. # pre & post are the js-pre/js-post options to emcc.
# They are injected inside the modularised code and # They are injected inside the modularised code and
@ -93,7 +88,7 @@ LDFLAGS += -Wall -Werror
CFLAGS_NATIVE = -fPIC CFLAGS_NATIVE = -fPIC
CXXFLAGS_NATIVE = -fPIC CXXFLAGS_NATIVE = -fPIC
EMCCFLAGS = --closure 1 --memory-init-file 0 -s NO_FILESYSTEM=1 -s INVOKE_RUN=0 -s MODULARIZE=1 -Wno-error=closure EMCCFLAGS = --closure 1 --memory-init-file 0 -s NO_FILESYSTEM=1 -s INVOKE_RUN=0 -s MODULARIZE=1
# Olm generally doesn't need a lot of memory to encrypt / decrypt its usual # Olm generally doesn't need a lot of memory to encrypt / decrypt its usual
# payloads (ie. Matrix messages), but we do need about 128K of heap to encrypt # payloads (ie. Matrix messages), but we do need about 128K of heap to encrypt
@ -103,29 +98,18 @@ EMCCFLAGS = --closure 1 --memory-init-file 0 -s NO_FILESYSTEM=1 -s INVOKE_RUN=0
# (This can't be changed by the app with wasm since it's baked into the wasm). # (This can't be changed by the app with wasm since it's baked into the wasm).
# (emscripten also mandates at least 16MB of memory for asm.js now, so # (emscripten also mandates at least 16MB of memory for asm.js now, so
# we don't use this for the legacy build.) # we don't use this for the legacy build.)
EMCCFLAGS_WASM += -s TOTAL_STACK=65536 -s TOTAL_MEMORY=262144 -s ALLOW_MEMORY_GROWTH EMCCFLAGS_WASM += -s TOTAL_STACK=65536 -s TOTAL_MEMORY=262144
EMCCFLAGS_ASMJS += -s WASM=0 EMCCFLAGS_ASMJS += -s WASM=0
EMCC.c = $(EMCC) $(CFLAGS) $(CPPFLAGS) -c -DNDEBUG -DOLM_STATIC_DEFINE=1 EMCC.c = $(EMCC) $(CFLAGS) $(CPPFLAGS) -c
EMCC.cc = $(EMCC) $(CXXFLAGS) $(CPPFLAGS) -c -DNDEBUG -DOLM_STATIC_DEFINE=1 EMCC.cc = $(EMCC) $(CXXFLAGS) $(CPPFLAGS) -c
EMCC_LINK = $(EMCC) $(LDFLAGS) $(EMCCFLAGS) EMCC_LINK = $(EMCC) $(LDFLAGS) $(EMCCFLAGS)
AFL_CC = afl-clang-fast
AFL_CXX = afl-clang-fast++
AFL.c = $(AFL_CC) $(CFLAGS) $(CPPFLAGS) -c AFL.c = $(AFL_CC) $(CFLAGS) $(CPPFLAGS) -c
AFL.cc = $(AFL_CXX) $(CXXFLAGS) $(CPPFLAGS) -c AFL.cc = $(AFL_CXX) $(CXXFLAGS) $(CPPFLAGS) -c
AFL_LINK.c = $(AFL_CC) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS) AFL_LINK.c = $(AFL_CC) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS)
AFL_LINK.cc = $(AFL_CXX) $(LDFLAGS) $(CXXFLAGS) $(CPPFLAGS) AFL_LINK.cc = $(AFL_CXX) $(LDFLAGS) $(CXXFLAGS) $(CPPFLAGS)
AFL_ASAN.c = AFL_USE_ASAN=1 $(AFL_CC) -m32 $(CFLAGS) $(CPPFLAGS) -c
AFL_ASAN.cc = AFL_USE_ASAN=1 $(AFL_CXX) -m32 $(CXXFLAGS) $(CPPFLAGS) -c
AFL_LINK_ASAN.c = AFL_USE_ASAN=1 $(AFL_CC) -m32 $(LDFLAGS) $(CFLAGS) $(CPPFLAGS)
AFL_LINK_ASAN.cc = AFL_USE_ASAN=1 $(AFL_CXX) -m32 $(LDFLAGS) $(CXXFLAGS) $(CPPFLAGS)
AFL_MSAN.c = AFL_USE_MSAN=1 $(AFL_CC) $(CFLAGS) $(CPPFLAGS) -c
AFL_MSAN.cc = AFL_USE_MSAN=1 $(AFL_CXX) $(CXXFLAGS) $(CPPFLAGS) -c
AFL_LINK_MSAN.c = AFL_USE_MSAN=1 $(AFL_CC) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS)
AFL_LINK_MSAN.cc = AFL_USE_MSAN=1 $(AFL_CXX) $(LDFLAGS) $(CXXFLAGS) $(CPPFLAGS)
# generate .d files when compiling # generate .d files when compiling
CPPFLAGS += -MMD CPPFLAGS += -MMD
@ -143,23 +127,12 @@ $(DEBUG_TARGET): LDFLAGS += $(DEBUG_OPTIMIZE_FLAGS)
$(TEST_BINARIES): CPPFLAGS += -Itests/include $(TEST_BINARIES): CPPFLAGS += -Itests/include
$(TEST_BINARIES): LDFLAGS += $(DEBUG_OPTIMIZE_FLAGS) -L$(BUILD_DIR) $(TEST_BINARIES): LDFLAGS += $(DEBUG_OPTIMIZE_FLAGS) -L$(BUILD_DIR)
$(FUZZER_OBJECTS): CFLAGS += $(FUZZER_OPTIMIZE_FLAGS) -D OLM_FUZZING=1 $(FUZZER_OBJECTS): CFLAGS += $(FUZZER_OPTIMIZE_FLAGS)
$(FUZZER_OBJECTS): CXXFLAGS += $(FUZZER_OPTIMIZE_FLAGS) -D OLM_FUZZING=1 $(FUZZER_OBJECTS): CXXFLAGS += $(FUZZER_OPTIMIZE_FLAGS)
$(FUZZER_DEBUG_OBJECTS): CFLAGS += $(DEBUG_OPTIMIZE_FLAGS) $(CFLAGS_NATIVE) -D OLM_FUZZING=1 $(FUZZER_BINARIES): CPPFLAGS += -Ifuzzers/include
$(FUZZER_DEBUG_OBJECTS): CXXFLAGS += $(DEBUG_OPTIMIZE_FLAGS) $(CXXFLAGS_NATIVE) -D OLM_FUZZING=1 $(FUZZER_BINARIES): LDFLAGS += $(FUZZER_OPTIMIZE_FLAGS) -L$(BUILD_DIR)
$(FUZZER_ASAN_OBJECTS): CFLAGS += $(FUZZER_OPTIMIZE_FLAGS) -D OLM_FUZZING=1 $(FUZZER_DEBUG_BINARIES): CPPFLAGS += -Ifuzzers/include
$(FUZZER_ASAN_OBJECTS): CXXFLAGS += $(FUZZER_OPTIMIZE_FLAGS) -D OLM_FUZZING=1 $(FUZZER_DEBUG_BINARIES): LDFLAGS += $(DEBUG_OPTIMIZE_FLAGS)
$(FUZZER_MSAN_OBJECTS): CFLAGS += $(FUZZER_OPTIMIZE_FLAGS) -D OLM_FUZZING=1
$(FUZZER_MSAN_OBJECTS): CXXFLAGS += $(FUZZER_OPTIMIZE_FLAGS) -D OLM_FUZZING=1
$(FUZZER_BINARIES): CPPFLAGS += -Ifuzzing/fuzzers/include
$(FUZZER_BINARIES): LDFLAGS += $(FUZZER_OPTIMIZE_FLAGS) -L$(BUILD_DIR) -lstdc++
$(FUZZER_ASAN_BINARIES): CPPFLAGS += -Ifuzzing/fuzzers/include
$(FUZZER_ASAN_BINARIES): LDFLAGS += $(FUZZER_OPTIMIZE_FLAGS) -L$(BUILD_DIR) -lstdc++
$(FUZZER_MSAN_BINARIES): CPPFLAGS += -Ifuzzing/fuzzers/include
$(FUZZER_MSAN_BINARIES): LDFLAGS += $(FUZZER_OPTIMIZE_FLAGS) -L$(BUILD_DIR) -lstdc++
$(FUZZER_DEBUG_BINARIES): CPPFLAGS += -Ifuzzing/fuzzers/include
$(FUZZER_DEBUG_BINARIES): LDFLAGS += $(DEBUG_OPTIMIZE_FLAGS) -lstdc++
$(JS_OBJECTS): CFLAGS += $(JS_OPTIMIZE_FLAGS) $(JS_OBJECTS): CFLAGS += $(JS_OPTIMIZE_FLAGS)
$(JS_OBJECTS): CXXFLAGS += $(JS_OPTIMIZE_FLAGS) $(JS_OBJECTS): CXXFLAGS += $(JS_OPTIMIZE_FLAGS)
@ -185,12 +158,6 @@ lib: $(RELEASE_TARGET)
.PHONY: lib .PHONY: lib
$(RELEASE_TARGET): $(RELEASE_OBJECTS) $(RELEASE_TARGET): $(RELEASE_OBJECTS)
@echo
@echo '****************************************************************************'
@echo '* WARNING: Building olm with make is deprecated. Please use cmake instead. *'
@echo '****************************************************************************'
@echo
$(CXX) $(LDFLAGS) --shared -fPIC \ $(CXX) $(LDFLAGS) --shared -fPIC \
$(OLM_LDFLAGS) \ $(OLM_LDFLAGS) \
$(OUTPUT_OPTION) $(RELEASE_OBJECTS) $(OUTPUT_OPTION) $(RELEASE_OBJECTS)
@ -215,39 +182,32 @@ $(STATIC_RELEASE_TARGET): $(RELEASE_OBJECTS)
js: $(JS_WASM_TARGET) $(JS_ASMJS_TARGET) js: $(JS_WASM_TARGET) $(JS_ASMJS_TARGET)
.PHONY: js .PHONY: js
wasm: $(WASM_TARGET)
.PHONY: wasm
$(WASM_TARGET): $(WASM_OBJECTS)
$(EMAR) rcs $@ $^
javascript/olm_prefix.js: javascript/olm_prefix.js.in Makefile common.mk
sed s/@VERSION@/$(VERSION)/ javascript/olm_prefix.js.in > $@
# Note that the output file we give to emcc determines the name of the # Note that the output file we give to emcc determines the name of the
# wasm file baked into the js, hence messing around outputting to olm.js # wasm file baked into the js, hence messing around outputting to olm.js
# and then renaming it. # and then renaming it.
$(JS_WASM_TARGET): $(JS_OBJECTS) $(JS_PRE) $(JS_POST) $(JS_EXPORTED_FUNCTIONS) $(JS_PREFIX) $(JS_SUFFIX) $(JS_WASM_TARGET): $(JS_OBJECTS) $(JS_PRE) $(JS_POST) $(JS_EXPORTED_FUNCTIONS) $(JS_PREFIX) $(JS_SUFFIX)
EMCC_CLOSURE_ARGS="--externs $(CURDIR)/$(JS_EXTERNS)" $(EMCC_LINK) \ EMCC_CLOSURE_ARGS="--externs $(JS_EXTERNS)" $(EMCC_LINK) \
$(EMCCFLAGS_WASM) \ $(EMCCFLAGS_WASM) \
$(foreach f,$(JS_PRE),--pre-js $(f)) \ $(foreach f,$(JS_PRE),--pre-js $(f)) \
$(foreach f,$(JS_POST),--post-js $(f)) \ $(foreach f,$(JS_POST),--post-js $(f)) \
$(foreach f,$(JS_PREFIX),--extern-pre-js $(f)) \
$(foreach f,$(JS_SUFFIX),--extern-post-js $(f)) \
-s "EXPORTED_FUNCTIONS=@$(JS_EXPORTED_FUNCTIONS)" \ -s "EXPORTED_FUNCTIONS=@$(JS_EXPORTED_FUNCTIONS)" \
-s "EXPORTED_RUNTIME_METHODS=$(JS_EXPORTED_RUNTIME_METHODS)" \ -s "EXTRA_EXPORTED_RUNTIME_METHODS=$(JS_EXTRA_EXPORTED_RUNTIME_METHODS)" \
-o $@ $(JS_OBJECTS) $(JS_OBJECTS) -o $@
mv $@ javascript/olmtmp.js
cat $(JS_PREFIX) javascript/olmtmp.js $(JS_SUFFIX) > $@
rm javascript/olmtmp.js
$(JS_ASMJS_TARGET): $(JS_OBJECTS) $(JS_PRE) $(JS_POST) $(JS_EXPORTED_FUNCTIONS) $(JS_PREFIX) $(JS_SUFFIX) $(JS_ASMJS_TARGET): $(JS_OBJECTS) $(JS_PRE) $(JS_POST) $(JS_EXPORTED_FUNCTIONS) $(JS_PREFIX) $(JS_SUFFIX)
EMCC_CLOSURE_ARGS="--externs $(CURDIR)/$(JS_EXTERNS)" $(EMCC_LINK) \ EMCC_CLOSURE_ARGS="--externs $(JS_EXTERNS)" $(EMCC_LINK) \
$(EMCCFLAGS_ASMJS) \ $(EMCCFLAGS_ASMJS) \
$(foreach f,$(JS_PRE),--pre-js $(f)) \ $(foreach f,$(JS_PRE),--pre-js $(f)) \
$(foreach f,$(JS_POST),--post-js $(f)) \ $(foreach f,$(JS_POST),--post-js $(f)) \
$(foreach f,$(JS_PREFIX),--extern-pre-js $(f)) \
$(foreach f,$(JS_SUFFIX),--extern-post-js $(f)) \
-s "EXPORTED_FUNCTIONS=@$(JS_EXPORTED_FUNCTIONS)" \ -s "EXPORTED_FUNCTIONS=@$(JS_EXPORTED_FUNCTIONS)" \
-s "EXPORTED_RUNTIME_METHODS=$(JS_EXPORTED_RUNTIME_METHODS)" \ -s "EXTRA_EXPORTED_RUNTIME_METHODS=$(JS_EXTRA_EXPORTED_RUNTIME_METHODS)" \
-o $@ $(JS_OBJECTS) $(JS_OBJECTS) -o $@
mv $@ javascript/olmtmp.js
cat $(JS_PREFIX) javascript/olmtmp.js $(JS_SUFFIX) > $@
rm javascript/olmtmp.js
build_tests: $(TEST_BINARIES) build_tests: $(TEST_BINARIES)
@ -257,13 +217,7 @@ test: build_tests
$$i || exit $$?; \ $$i || exit $$?; \
done done
test_mem: build_tests fuzzers: $(FUZZER_BINARIES) $(FUZZER_DEBUG_BINARIES)
for i in $(TEST_BINARIES); do \
echo $$i; \
valgrind -q --leak-check=yes --exit-on-first-error=yes --error-exitcode=1 $$i || exit $$?; \
done
fuzzers: $(FUZZER_BINARIES) $(FUZZER_ASAN_BINARIES) $(FUZZER_MSAN_BINARIES) $(FUZZER_DEBUG_BINARIES)
.PHONY: fuzzers .PHONY: fuzzers
$(JS_EXPORTED_FUNCTIONS): $(PUBLIC_HEADERS) $(JS_EXPORTED_FUNCTIONS): $(PUBLIC_HEADERS)
@ -275,19 +229,19 @@ all: test js lib debug doc
install-headers: $(PUBLIC_HEADERS) install-headers: $(PUBLIC_HEADERS)
test -d $(DESTDIR)$(PREFIX)/include/olm || $(call mkdir,$(DESTDIR)$(PREFIX)/include/olm) test -d $(DESTDIR)$(PREFIX)/include/olm || $(call mkdir,$(DESTDIR)$(PREFIX)/include/olm)
install $(PUBLIC_HEADERS) $(DESTDIR)$(PREFIX)/include/olm/ install -Dm644 $(PUBLIC_HEADERS) $(DESTDIR)$(PREFIX)/include/olm/
.PHONY: install-headers .PHONY: install-headers
install-debug: debug install-headers install-debug: debug install-headers
test -d $(DESTDIR)$(PREFIX)/lib || $(call mkdir,$(DESTDIR)$(PREFIX)/lib) test -d $(DESTDIR)$(PREFIX)/lib || $(call mkdir,$(DESTDIR)$(PREFIX)/lib)
install $(DEBUG_TARGET) $(DESTDIR)$(PREFIX)/lib/libolm_debug.$(SO).$(VERSION) install -Dm755 $(DEBUG_TARGET) $(DESTDIR)$(PREFIX)/lib/libolm_debug.$(SO).$(VERSION)
ln -sf libolm_debug.$(SO).$(VERSION) $(DESTDIR)$(PREFIX)/lib/libolm_debug.$(SO).$(MAJOR) ln -sf libolm_debug.$(SO).$(VERSION) $(DESTDIR)$(PREFIX)/lib/libolm_debug.$(SO).$(MAJOR)
ln -sf libolm_debug.$(SO).$(VERSION) $(DESTDIR)$(PREFIX)/lib/libolm_debug.$(SO) ln -sf libolm_debug.$(SO).$(VERSION) $(DESTDIR)$(PREFIX)/lib/libolm_debug.$(SO)
.PHONY: install-debug .PHONY: install-debug
install: lib install-headers install: lib install-headers
test -d $(DESTDIR)$(PREFIX)/lib || $(call mkdir,$(DESTDIR)$(PREFIX)/lib) test -d $(DESTDIR)$(PREFIX)/lib || $(call mkdir,$(DESTDIR)$(PREFIX)/lib)
install $(RELEASE_TARGET) $(DESTDIR)$(PREFIX)/lib/libolm.$(SO).$(VERSION) install -Dm755 $(RELEASE_TARGET) $(DESTDIR)$(PREFIX)/lib/libolm.$(SO).$(VERSION)
ln -sf libolm.$(SO).$(VERSION) $(DESTDIR)$(PREFIX)/lib/libolm.$(SO).$(MAJOR) ln -sf libolm.$(SO).$(VERSION) $(DESTDIR)$(PREFIX)/lib/libolm.$(SO).$(MAJOR)
ln -sf libolm.$(SO).$(VERSION) $(DESTDIR)$(PREFIX)/lib/libolm.$(SO) ln -sf libolm.$(SO).$(VERSION) $(DESTDIR)$(PREFIX)/lib/libolm.$(SO)
.PHONY: install .PHONY: install
@ -324,21 +278,13 @@ $(BUILD_DIR)/javascript/%.o: %.cpp
$(call mkdir,$(dir $@)) $(call mkdir,$(dir $@))
$(EMCC.cc) $(OUTPUT_OPTION) $< $(EMCC.cc) $(OUTPUT_OPTION) $<
$(BUILD_DIR)/wasm/%.o: %.c
$(call mkdir,$(dir $@))
$(EMCC.c) $(OUTPUT_OPTION) $<
$(BUILD_DIR)/wasm/%.o: %.cpp
$(call mkdir,$(dir $@))
$(EMCC.cc) $(OUTPUT_OPTION) $<
$(BUILD_DIR)/tests/%: tests/%.c $(DEBUG_OBJECTS) $(BUILD_DIR)/tests/%: tests/%.c $(DEBUG_OBJECTS)
$(call mkdir,$(dir $@)) $(call mkdir,$(dir $@))
$(LINK.c) -o $@ $< $(DEBUG_OBJECTS) $(LOADLIBES) $(LDLIBS) $(LINK.c) $< $(DEBUG_OBJECTS) $(LOADLIBES) $(LDLIBS) -o $@
$(BUILD_DIR)/tests/%: tests/%.cpp $(DEBUG_OBJECTS) $(BUILD_DIR)/tests/%: tests/%.cpp $(DEBUG_OBJECTS)
$(call mkdir,$(dir $@)) $(call mkdir,$(dir $@))
$(LINK.cc) -o $@ $< $(DEBUG_OBJECTS) $(LOADLIBES) $(LDLIBS) $(LINK.cc) $< $(DEBUG_OBJECTS) $(LOADLIBES) $(LDLIBS) -o $@
$(BUILD_DIR)/fuzzers/objects/%.o: %.c $(BUILD_DIR)/fuzzers/objects/%.o: %.c
$(call mkdir,$(dir $@)) $(call mkdir,$(dir $@))
@ -348,61 +294,21 @@ $(BUILD_DIR)/fuzzers/objects/%.o: %.cpp
$(call mkdir,$(dir $@)) $(call mkdir,$(dir $@))
$(AFL.cc) $(OUTPUT_OPTION) $< $(AFL.cc) $(OUTPUT_OPTION) $<
$(BUILD_DIR)/fuzzers/objects/asan_%.o: %.c $(BUILD_DIR)/fuzzers/fuzz_%: fuzzers/fuzz_%.c $(FUZZER_OBJECTS)
$(call mkdir,$(dir $@)) $(AFL_LINK.c) $< $(FUZZER_OBJECTS) $(LOADLIBES) $(LDLIBS) -o $@
$(AFL_ASAN.c) $(OUTPUT_OPTION) $<
$(BUILD_DIR)/fuzzers/objects/asan_%.o: %.cpp $(BUILD_DIR)/fuzzers/fuzz_%: fuzzers/fuzz_%.cpp $(FUZZER_OBJECTS)
$(call mkdir,$(dir $@)) $(AFL_LINK.cc) $< $(FUZZER_OBJECTS) $(LOADLIBES) $(LDLIBS) -o $@
$(AFL_ASAN.cc) $(OUTPUT_OPTION) $<
$(BUILD_DIR)/fuzzers/objects/msan_%.o: %.c $(BUILD_DIR)/fuzzers/debug_%: fuzzers/fuzz_%.c $(DEBUG_OBJECTS)
$(call mkdir,$(dir $@)) $(LINK.c) $< $(DEBUG_OBJECTS) $(LOADLIBES) $(LDLIBS) -o $@
$(AFL_MSAN.c) $(OUTPUT_OPTION) $<
$(BUILD_DIR)/fuzzers/objects/msan_%.o: %.cpp $(BUILD_DIR)/fuzzers/debug_%: fuzzers/fuzz_%.cpp $(DEBUG_OBJECTS)
$(call mkdir,$(dir $@)) $(LINK.cc) $< $(DEBUG_OBJECTS) $(LOADLIBES) $(LDLIBS) -o $@
$(AFL_MSAN.cc) $(OUTPUT_OPTION) $<
$(BUILD_DIR)/fuzzers/objects/debug_%.o: %.c
$(call mkdir,$(dir $@))
$(COMPILE.c) $(OUTPUT_OPTION) $<
$(BUILD_DIR)/fuzzers/objects/debug_%.o: %.cpp
$(call mkdir,$(dir $@))
$(COMPILE.cc) $(OUTPUT_OPTION) $<
$(BUILD_DIR)/fuzzers/fuzz_%: fuzzing/fuzzers/fuzz_%.c $(FUZZER_OBJECTS)
$(AFL_LINK.c) -o $@ $< $(FUZZER_OBJECTS) $(LOADLIBES) $(LDLIBS)
$(BUILD_DIR)/fuzzers/fuzz_%: fuzzing/fuzzers/fuzz_%.cpp $(FUZZER_OBJECTS)
$(AFL_LINK.cc) -o $@ $< $(FUZZER_OBJECTS) $(LOADLIBES) $(LDLIBS)
$(BUILD_DIR)/fuzzers/debug_%: fuzzing/fuzzers/fuzz_%.c $(FUZZER_DEBUG_OBJECTS)
$(LINK.c) -o $@ $< $(FUZZER_DEBUG_OBJECTS) $(LOADLIBES) $(LDLIBS)
$(BUILD_DIR)/fuzzers/debug_%: fuzzing/fuzzers/fuzz_%.cpp $(FUZZER_DEBUG_OBJECTS)
$(LINK.cc) -o $@ $< $(FUZZER_DEBUG_OBJECTS) $(LOADLIBES) $(LDLIBS)
$(BUILD_DIR)/fuzzers/fuzz_%_asan: fuzzing/fuzzers/fuzz_%.c $(FUZZER_ASAN_OBJECTS)
$(AFL_LINK_ASAN.c) -o $@ $< $(FUZZER_ASAN_OBJECTS) $(LOADLIBES) $(LDLIBS)
$(BUILD_DIR)/fuzzers/fuzz_%_asan: fuzzing/fuzzers/fuzz_%.cpp $(FUZZER_ASAN_OBJECTS)
$(AFL_LINK_ASAN.cc) -o $@ $< $(FUZZER_ASAN_OBJECTS) $(LOADLIBES) $(LDLIBS)
$(BUILD_DIR)/fuzzers/fuzz_%_msan: fuzzing/fuzzers/fuzz_%.c $(FUZZER_MSAN_OBJECTS)
$(AFL_LINK_MSAN.c) -o $@ $< $(FUZZER_MSAN_OBJECTS) $(LOADLIBES) $(LDLIBS)
$(BUILD_DIR)/fuzzers/fuzz_%_msan: fuzzing/fuzzers/fuzz_%.cpp $(FUZZER_MSAN_OBJECTS)
$(AFL_LINK_MSAN.cc) -o $@ $< $(FUZZER_MSAN_OBJECTS) $(LOADLIBES) $(LDLIBS)
%.html: %.rst %.html: %.rst
rst2html $< $@ rst2html $< $@
%.html: %.md
pandoc --from markdown --to html5 --standalone --lua-filter gitlab-math.lua --katex -o $@ $<
### dependencies ### dependencies
-include $(RELEASE_OBJECTS:.o=.d) -include $(RELEASE_OBJECTS:.o=.d)
@ -410,10 +316,5 @@ $(BUILD_DIR)/fuzzers/fuzz_%_msan: fuzzing/fuzzers/fuzz_%.cpp $(FUZZER_MSAN_OBJEC
-include $(JS_OBJECTS:.o=.d) -include $(JS_OBJECTS:.o=.d)
-include $(TEST_BINARIES:=.d) -include $(TEST_BINARIES:=.d)
-include $(FUZZER_OBJECTS:.o=.d) -include $(FUZZER_OBJECTS:.o=.d)
-include $(FUZZER_DEBUG_OBJECTS:.o=.d)
-include $(FUZZER_ASAN_OBJECTS:.o=.d)
-include $(FUZZER_MSAN_OBJECTS:.o=.d)
-include $(FUZZER_BINARIES:=.d) -include $(FUZZER_BINARIES:=.d)
-include $(FUZZER_ASAN_BINARIES:=.d)
-include $(FUZZER_MSAN_BINARIES:=.d)
-include $(FUZZER_DEBUG_BINARIES:=.d) -include $(FUZZER_DEBUG_BINARIES:=.d)

View file

@ -2,8 +2,8 @@ Pod::Spec.new do |s|
# The libolm version # The libolm version
MAJOR = 3 MAJOR = 3
MINOR = 2 MINOR = 1
PATCH = 16 PATCH = 4
s.name = "OLMKit" s.name = "OLMKit"
s.version = "#{MAJOR}.#{MINOR}.#{PATCH}" s.version = "#{MAJOR}.#{MINOR}.#{PATCH}"

View file

@ -1,15 +1,14 @@
// swift-tools-version:5.3 // swift-tools-version:5.2
import PackageDescription import PackageDescription
let major = 3, minor = 2, patch = 16 let version = ( major: 3, minor: 1, patch: 4 )
let package = Package( let package = Package(
name: "Olm", name: "Olm",
platforms: [.iOS(.v8), .macOS(.v10_10)],
products: [ products: [
.library(name: "libolm", targets: ["libolm"]), .library(name: "libolm", targets: ["libolm"]),
.library(name: "OLMKit", targets: ["OLMKit"]) .library(name: "OLMKit", targets: ["OLMKit"]),
], ],
targets: [ targets: [
.target( .target(
@ -21,29 +20,38 @@ let package = Package(
"lib/crypto-algorithms/sha256.c", "lib/crypto-algorithms/sha256.c",
"lib/curve25519-donna/curve25519-donna.c" "lib/curve25519-donna/curve25519-donna.c"
], ],
//publicHeadersPath: "include",
publicHeadersPath: "include/public",
cSettings: [ cSettings: [
.define("OLMLIB_VERSION_MAJOR", to: String(version.major)),
.define("OLMLIB_VERSION_MINOR", to: String(version.minor)),
.define("OLMLIB_VERSION_PATCH", to: String(version.patch)),
.headerSearchPath("lib"), .headerSearchPath("lib"),
.define("OLMLIB_VERSION_MAJOR", to: "\(major)"), .headerSearchPath("include"),
.define("OLMLIB_VERSION_MINOR", to: "\(minor)"), .unsafeFlags([ "-Wall", "-Werror" ])
.define("OLMLIB_VERSION_PATCH", to: "\(patch)")
] ]
), ),
.target( .target(
name: "OLMKit", name: "OLMKit",
dependencies: [ "libolm" ], dependencies: [ "libolm" ],
path: "xcode/OLMKit", path: "xcode",
exclude: ["Info.plist"], exclude: [ "OLMKit/Info.plist" ],
sources: [ "OLMKit" ],
publicHeadersPath: "PublicHeaders",
cSettings: [ cSettings: [
.headerSearchPath("..") .headerSearchPath("."),
.unsafeFlags([
"-Wno-unused-command-line-argument",
"-fmodules", "-fcxx-modules"
])
] ]
), ),
.testTarget( .testTarget(
name: "OLMKitTests", name: "OLMKitTests",
dependencies: ["OLMKit"], dependencies: [ "OLMKit", "libolm" ],
path: "xcode/OLMKitTests", path: "xcode/OLMKitTests",
exclude: ["Info.plist"],
cSettings: [ cSettings: [
.headerSearchPath("..") .headerSearchPath(".."),
] ]
) )
], ],

237
README.md
View file

@ -9,133 +9,52 @@ The specification of the Olm ratchet can be found in [docs/olm.md](docs/olm.md).
This library also includes an implementation of the Megolm cryptographic This library also includes an implementation of the Megolm cryptographic
ratchet, as specified in [docs/megolm.md](docs/megolm.md). ratchet, as specified in [docs/megolm.md](docs/megolm.md).
## Installing
### Linux and other Unix-like systems
Your distribution may have pre-compiled packages available. If not, or if you
need a newer version, you will need to compile from source. See the "Building"
section below for more details.
### macOS
The easiest way to install on macOS is via Homebrew. If you do not have
Homebrew installed, follow the instructions at https://brew.sh/ to install it.
You can then install libolm by running
```bash
brew install libolm
```
If you also need the Python packages, you can run
```bash
pip3 install python-olm --global-option="build_ext" --global-option="--include-dirs="`brew --prefix libolm`"/include" --global-option="--library-dirs="`brew --prefix libolm`"/lib"
```
Note that this will install an older version of the Python bindings, which may
be missing some functions. If you need the latest version, you will need to
build from source.
### Windows
You will need to build from source. See the "Building" section below for more
details.
### Bindings
#### JavaScript
You can use pre-built npm packages, available at
<https://gitlab.matrix.org/matrix-org/olm/-/packages?type=npm>.
#### Python
A Python source package and pre-built packages for certain architectures from
<https://pypi.org/project/python-olm/>. If a pre-built package is not
available for your architecture, you will need:
- cmake (recommended) or GNU make
- a C/C++ compiler
to build the source package.
You can then run `pip install python-olm`.
Currently, we try to provide packages for all supported versions of Python on
x86-64, i686, and aarch64, but we cannot guarantee that packages for all
versions will be available on all architectures.
#### Android
Pre-built Android bindings are available at
<https://gitlab.matrix.org/matrix-org/olm/-/packages?type=Maven>.
## Building ## Building
To build olm as a shared library run: To build olm as a shared library run either:
```bash ```bash
cmake . -Bbuild cmake . -Bbuild
cmake --build build cmake --build build
``` ```
To run the tests, run: or:
```bash
make
```
Using cmake is the preferred method for building the shared library; the
Makefile may be removed in the future.
To run the tests when using cmake, run:
```bash ```bash
cd build/tests cd build/tests
ctest . ctest .
``` ```
To run the tests when using make, run:
To build olm as a static library (which still needs libstdc++ dynamically) run:
```bash ```bash
cmake . -Bbuild -DBUILD_SHARED_LIBS=NO make test
cmake --build build
``` ```
The library can also be used as a dependency with CMake using: To build the JavaScript bindings, install emscripten from http://kripken.github.io/emscripten-site/ and then run:
```cmake
find_package(Olm::Olm REQUIRED)
target_link_libraries(my_exe Olm::Olm)
```
### Bindings
#### JavaScript
The recommended way to build the JavaScript bindings is using
[Nix](https://nixos.org/). With Nix, you can run
```bash
nix build .\#javascript
```
to build the bindings.
If you do not have Nix you can, install emscripten from https://emscripten.org/
and then run:
```bash ```bash
make js make js
``` ```
Emscripten can also be run via Docker, in which case, you need to pass through Note that if you run emscripten in a docker container, you need to pass through
the EMCC_CLOSURE_ARGS environment variable. the EMCC_CLOSURE_ARGS environment variable.
#### Android
To build the android project for Android bindings, run: To build the android project for Android bindings, run:
```bash ```bash
cd android cd android
./gradlew clean build ./gradlew clean assembleRelease
``` ```
#### Objective-C
To build the Xcode workspace for Objective-C bindings, run: To build the Xcode workspace for Objective-C bindings, run:
```bash ```bash
@ -144,9 +63,7 @@ pod install
open OLMKit.xcworkspace open OLMKit.xcworkspace
``` ```
#### Python To build the Python bindings, first build olm as a shared library as above, and
To build the Python 3 bindings, first build olm as a library as above, and
then run: then run:
```bash ```bash
@ -154,62 +71,38 @@ cd python
make make
``` ```
### Using make instead of cmake to make both the Python 2 and Python 3 bindings. To make only one version, use
``make olm-python2`` or ``make olm-python3`` instead of just ``make``.
**WARNING:** Using cmake is the preferred method for building the olm library; To build olm as a static library (which still needs libstdc++ dynamically) run
the Makefile may be removed in the future or have functionality removed. In either:
addition, the Makefile may make certain assumptions about your system and is
not as well tested.
To build olm as a dynamic library, run:
```bash ```bash
make cmake . -Bbuild -DBUILD_SHARED_LIBS=NO
cmake --build build
``` ```
To run the tests, run: or
```bash
make test
```
To build olm as a static library, run:
```bash ```bash
make static make static
``` ```
## Bindings The library can also be used as a dependency with CMake using:
libolm can be used in different environments using bindings. In addition to the ```cmake
JavaScript, Python, Java (Android), and Objective-C bindings included in this find_package(Olm::Olm REQUIRED)
repository, some bindings are (in alphabetical order): target_link_libraries(my_exe Olm::Olm)
```
- [cl-megolm](https://github.com/K1D77A/cl-megolm) (MIT) Common Lisp bindings
- [dart-olm](https://gitlab.com/famedly/company/frontend/libraries/dart-olm) (AGPLv3) Dart bindings
- [Dhole/go-olm](https://github.com/Dhole/go-olm) (Apache-2.0) Go bindings
- [jOlm](https://github.com/brevilo/jolm) (Apache-2.0) Java bindings
- [libQtOlm](https://gitlab.com/b0/libqtolm/) (GPLv3) Qt bindings
- [matrix-kt](https://github.com/Dominaezzz/matrix-kt) (Apache-2.0) Kotlin
library for Matrix, including Olm methods
- [maunium.net/go/mautrix/crypto/olm](https://github.com/tulir/mautrix-go/tree/master/crypto/olm)
(Apache-2.0) fork of Dhole/go-olm
- [nim-olm](https://codeberg.org/BarrOff/nim-olm) (MIT) Nim bindings
- [olm-sys](https://gitlab.gnome.org/BrainBlasted/olm-sys) (Apache-2.0) Rust
bindings
- [Trixnity](https://gitlab.com/trixnity/trixnity) (Apache-2.0) Kotlin SDK for
Matrix, including Olm bindings
Note that bindings may have a different license from libolm, and are *not*
endorsed by the Matrix.org Foundation C.I.C.
## Release process ## Release process
First: bump version numbers in ``common.mk``, ``CMakeLists.txt``, First: bump version numbers in ``common.mk``, ``CMakeLists.txt``,
``javascript/package.json``, ``python/pyproject.toml``, ``OLMKit.podspec``, ``javascript/package.json``, ``python/olm/__version__.py``, ``OLMKit.podspec``,
``Package.swift``, and ``android/gradle.properties``. and ``android/olm-sdk/build.gradle`` (``versionCode``, ``versionName`` and
``version``).
Also, ensure the changelog is up to date, and that everything is committed to Also, ensure the changelog is up to date, and that everyting is committed to
git. git.
It's probably sensible to do the above on a release branch (``release-vx.y.z`` It's probably sensible to do the above on a release branch (``release-vx.y.z``
@ -223,13 +116,11 @@ make test
# build and test JS wrapper # build and test JS wrapper
make js make js
(cd javascript && \ (cd javascript && npm run test)
npm run test && \ npm pack javascript
sha256sum olm.js olm_legacy.js olm.wasm > checksums.txt && \
gpg -b -a -u F75FDC22C1DE8453 checksums.txt && \
npm publish)
VERSION=x.y.z VERSION=x.y.z
scp olm-$VERSION.tgz packages@ares.matrix.org:packages/npm/olm/
git tag $VERSION -s git tag $VERSION -s
git push --tags git push --tags
@ -242,19 +133,43 @@ pod trunk push OLMKit.podspec --use-libraries --allow-warnings
pod search OLMKit pod search OLMKit
``` ```
Python and JavaScript packages are published to the registry at # libolm/OLMKit Swift Package Manager Package
<https://gitlab.matrix.org/matrix-org/olm/-/packages>. The GitLab
documentation contains instructions on how to set up twine (Python) and npm
(JavaScript) to upload to the registry.
To publish the Android library to MavenCentral (you will need some secrets), in the /android folder: ## Swift Example
- Run the command `./gradlew clean build publish --no-daemon --no-parallel --stacktrace`. The generated AAR must be approx 500 kb.
- Connect to https://s01.oss.sonatype.org Package.swift:
- Click on Staging Repositories and check the the files have been uploaded ```swift
- Click on close // swift-tools-version:5.2
- Wait (check Activity tab until step "Repository closed" is displayed)
- Click on release. The staging repository will disappear import PackageDescription
- Check that the release is available in https://repo1.maven.org/maven2/org/matrix/android/olm-sdk/ (it can take a few minutes)
let package = Package(
name: "testolm",
dependencies: [
.package(url: "git@github.com:helje5/Olm.git",
.branch("feature/swift-package-manager-c"))
],
targets: [
.target(
name: "testolm",
dependencies: [ .product(name: "OLMKit", package: "Olm") ]),
.testTarget(
name: "testolmTests",
dependencies: ["testolm"]),
]
)
```
main.swift:
```swift
import OLMKit
guard let bob = OLMAccount(newAccount: ()) else { exit(42) }
bob.generateOneTimeKeys(5)
guard let idKey = bob.identityKeys()?["curve25519"] else { exit(1337) }
print("key:", idKey)
```
## Design ## Design
@ -304,16 +219,12 @@ Please see [CONTRIBUTING.md](CONTRIBUTING.md) when making contributions to the l
Olm 1.3.0 was independently assessed by NCC Group's Cryptography Services Olm 1.3.0 was independently assessed by NCC Group's Cryptography Services
Practive in September 2016 to check for security issues: you can read all Practive in September 2016 to check for security issues: you can read all
about it at about it at
https://www.nccgroup.com/globalassets/our-research/us/public-reports/2016/november/ncc_group_olm_cryptogrpahic_review_2016_11_01.pdf https://www.nccgroup.trust/us/our-research/matrix-olm-cryptographic-review/
and https://matrix.org/blog/2016/11/21/matrixs-olm-end-to-end-encryption-security-assessment-released-and-implemented-cross-platform-on-riot-at-last/ and https://matrix.org/blog/2016/11/21/matrixs-olm-end-to-end-encryption-security-assessment-released-and-implemented-cross-platform-on-riot-at-last/
## Security issues
If you think you found a security issue in libolm, any of its bindings or the Olm/Megolm protocols, please follow our [Security Disclosure Policy](https://matrix.org/security-disclosure-policy/) to report.
## Bug reports ## Bug reports
For non-sensitive bugs, please file bug reports at https://github.com/matrix-org/olm/issues. Please file bug reports at https://github.com/matrix-org/olm/issues
## What's an olm? ## What's an olm?

View file

@ -1,29 +0,0 @@
# Cross-compile for Windows (64-bit) using Mingw-w64
# Build using:
# cmake . -Bbuild -DCMAKE_TOOLCHAIN_FILE=Windows64.cmake
# cmake --build build
# from @ticho:cyberdi.sk
# https://paste.debian.net/1201338/
# the name of the target operating system
SET(CMAKE_SYSTEM_NAME Windows)
# which compilers to use for C and C++
SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc-posix)
SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++-posix)
SET(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
# here is the target environment located
SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32)
# adjust the default behaviour of the FIND_XXX() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# static-link against the standard libraries
set(CMAKE_CXX_STANDARD_LIBRARIES "-static-libgcc -static-libstdc++")

BIN
android/.DS_Store vendored Normal file

Binary file not shown.

View file

@ -1,46 +0,0 @@
# TODO: consider replacing this with a smaller image
image: docker.io/inovex/gitlab-ci-android
stages:
- build
- test
variables:
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
before_script:
- export GRADLE_USER_HOME=$(pwd)/.gradle
- export ANDROID_HOME=${ANDROID_SDK_HOME}
- echo "sdk.dir=${ANDROID_SDK_HOME}" > ./android/local.properties
- echo "ndk.dir=${ANDROID_NDK_HOME}" >> ./android/local.properties
- cp -R $ANDROID_SDK_ROOT/licenses ./android/.
- chmod +x ./android/gradlew
cache:
key: ${CI_PROJECT_ID}
paths:
- android/.gradle/
build:android:aar:
stage: build
tags:
- docker
script:
- pushd android
- ./gradlew clean assembleRelease
artifacts:
expire_in: 1 weeks
paths:
- android/olm-sdk/build/outputs/aar/*.aar
- android/local.properties
test:android:aar:
stage: test
tags:
- docker
script:
- pushd android
- ./gradlew assembleAndroidTest
# TODO: Add emulator to run tests
needs:
- build:android:aar

View file

@ -5,21 +5,25 @@ OlmLibSdk exposes an android wrapper to libolm.
Installation Installation
------------ ------------
Create a libs directory in your project directory
Copy the olm-sdk.aar into it.
Android Olm library is released on MavenCentral. In your build.gradle file, add in the android section::
Add this dependency to your project: repositories {
flatDir {
dir 'libs'
}
}
```groovy Add in the dependencies category::
implementation "org.matrix.android:olm:3.2.8"
```
Latest version: ![Latest version](https://img.shields.io/maven-central/v/org.matrix.android/olm) compile(name: 'olm-sdk', ext: 'aar')
Development Development
----------- -----------
import the project from the ``android/`` path. import the project from the ``android/`` path.
The project contains some JNI files and some Java wrapper files. The project contains some JNI files and some Java wraper files.
The project contains some tests under AndroidTests package. The project contains some tests under AndroidTests package.

View file

@ -2,14 +2,12 @@
buildscript { buildscript {
repositories { repositories {
mavenCentral() jcenter()
google() google()
} }
dependencies { dependencies {
// Release notes of Android Gradle Plugin (AGP): classpath 'com.android.tools.build:gradle:3.1.3'
// https://developer.android.com/studio/releases/gradle-plugin
classpath 'com.android.tools.build:gradle:7.0.4'
classpath 'com.vanniktech:gradle-maven-publish-plugin:0.18.0'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
} }
@ -17,20 +15,9 @@ buildscript {
allprojects { allprojects {
repositories { repositories {
mavenCentral() jcenter()
google() google()
} }
plugins.withId("com.vanniktech.maven.publish.base") {
group = project.getProperties().getOrDefault("GROUP", "0.0.0")
version = project.getProperties().getOrDefault("VERSION_NAME", "name")
mavenPublishing {
publishToMavenCentral("S01")
pomFromGradleProperties()
signAllPublications()
}
}
} }
task clean(type: Delete) { task clean(type: Delete) {

View file

@ -19,31 +19,4 @@
#systemProp.https.proxyHost=batproxy #systemProp.https.proxyHost=batproxy
#systemProp.http.proxyPort=8080 #systemProp.http.proxyPort=8080
android.useAndroidX=true
org.gradle.configureondemand=false org.gradle.configureondemand=false
# Maven publication
# Ref: https://github.com/vanniktech/gradle-maven-publish-plugin
GROUP=org.matrix.android
POM_ARTIFACT_ID=olm
VERSION_NAME=3.2.16
POM_PACKAGING=aar
POM_NAME=Olm Android wrapper
POM_DESCRIPTION=An Android wrapper to libolm.
POM_INCEPTION_YEAR=2021
POM_URL=https://gitlab.matrix.org/matrix-org/olm
POM_LICENSE_NAME=The Apache Software License, Version 2.0
POM_LICENCE_URL=https://www.apache.org/licenses/LICENSE-2.0.txt
POM_LICENCE_DIST=repo
POM_SCM_URL=https://gitlab.matrix.org/matrix-org/olm
POM_SCM_CONNECTION=scm:git:https://gitlab.matrix.org/matrix-org/olm.git
POM_SCM_DEV_CONNECTION=scm:git:ssh://git@gitlab.int.matrix.org:matrix-org/olm.git
POM_DEVELOPER_ID=matrixdev
POM_DEVELOPER_NAME=matrixdev
POM_DEVELOPER_URL=https://gitlab.matrix.org/matrix-org
POM_DEVELOPER_EMAIL=android@element.io

View file

@ -1,6 +1,6 @@
#Thu Oct 13 09:38:01 CEST 2016
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionSha256Sum=c9490e938b221daf0094982288e4038deed954a3f12fb54cbf270ddf4e37d879
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-all.zip

View file

@ -1,26 +1,17 @@
import org.apache.tools.ant.taskdefs.condition.Os import org.apache.tools.ant.taskdefs.condition.Os
import com.vanniktech.maven.publish.AndroidLibrary
import com.vanniktech.maven.publish.JavadocJar
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
apply plugin: "com.vanniktech.maven.publish.base"
android { android {
compileSdk 31 compileSdkVersion 28
defaultConfig { defaultConfig {
minSdk 14 minSdkVersion 11
targetSdk 31 targetSdkVersion 28
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" versionCode 314
versionName "3.1.4"
buildConfigField "String", "OLM_VERSION", "\"${project.getProperties().getOrDefault("VERSION_NAME", "0.0.0")}\"" version "3.1.4"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
// The following argument makes the Android Test Orchestrator run its
// "pm clear" command after each test invocation. This command ensures
// that the app's state is completely cleared between tests.
testInstrumentationRunnerArguments clearPackageData: 'true'
buildConfigField "String", "OLM_VERSION", "\"${project.getProperties().getOrDefault("VERSION_NAME", "0.0.0")}\""
} }
buildTypes { buildTypes {
debug { debug {
@ -69,8 +60,7 @@ android {
} }
tasks.withType(JavaCompile) { tasks.withType(JavaCompile) {
compileTask -> compileTask -> if (compileTask.name.startsWith('compileDebugJava')) {
if (compileTask.name.startsWith('compileDebugJava')) {
println 'test compile: Debug' println 'test compile: Debug'
compileTask.dependsOn ndkBuildNativeDebug compileTask.dependsOn ndkBuildNativeDebug
} else if (compileTask.name.startsWith('compileReleaseJava')) { } else if (compileTask.name.startsWith('compileReleaseJava')) {
@ -80,27 +70,6 @@ android {
compileTask.dependsOn buildJavaDoc compileTask.dependsOn buildJavaDoc
} }
task androidJavadocs(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
android.libraryVariants.all { variant ->
if (variant.name == 'release') {
owner.classpath += variant.javaCompileProvider.get().classpath
}
}
exclude '**/R.html', '**/R.*.html', '**/index.html'
}
task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
archiveClassifier.set('javadoc')
from androidJavadocs.destinationDir
}
task androidSourcesJar(type: Jar) {
archiveClassifier.set('sources')
from android.sourceSets.main.java.srcDirs
}
clean.dependsOn cleanNative clean.dependsOn cleanNative
@ -112,11 +81,6 @@ android {
} }
} }
} }
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
} }
def getNdkFolder() { def getNdkFolder() {
@ -153,15 +117,9 @@ def gitRevisionDate() {
} }
dependencies { dependencies {
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.12'
androidTestImplementation 'junit:junit:4.13.2' androidTestImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support:support-annotations:28.0.0'
androidTestImplementation 'androidx.test:core:1.4.0' androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'androidx.test:runner:1.4.0' androidTestImplementation 'com.android.support.test:rules:1.0.2'
androidTestImplementation 'androidx.test:rules:1.4.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
}
mavenPublishing {
configure(new AndroidLibrary(new JavadocJar.Empty(), false))
} }

View file

@ -18,12 +18,12 @@
package org.matrix.olm; package org.matrix.olm;
import android.content.Context; import android.content.Context;
import android.support.test.runner.AndroidJUnit4;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import androidx.test.core.app.ApplicationProvider; import org.json.JSONException;
import androidx.test.ext.junit.runners.AndroidJUnit4; import org.json.JSONObject;
import org.junit.After; import org.junit.After;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Before; import org.junit.Before;
@ -41,13 +41,11 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.util.Map; import java.util.Map;
import static org.junit.Assert.assertEquals; import static android.support.test.InstrumentationRegistry.getInstrumentation;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING) @FixMethodOrder(MethodSorters.NAME_ASCENDING)
@ -67,7 +65,7 @@ public class OlmAccountTest {
String olmLibVersion = mOlmManager.getOlmLibVersion(); String olmLibVersion = mOlmManager.getOlmLibVersion();
assertNotNull(olmLibVersion); assertNotNull(olmLibVersion);
String olmSdkVersion = mOlmManager.getDetailedVersion(ApplicationProvider.getApplicationContext()); String olmSdkVersion = mOlmManager.getDetailedVersion(getInstrumentation().getContext());
assertNotNull(olmLibVersion); assertNotNull(olmLibVersion);
Log.d(LOG_TAG, "## setUpClass(): Versions - Android Olm SDK = "+olmSdkVersion+" Olm lib ="+olmLibVersion); Log.d(LOG_TAG, "## setUpClass(): Versions - Android Olm SDK = "+olmSdkVersion+" Olm lib ="+olmLibVersion);
} }
@ -98,12 +96,12 @@ public class OlmAccountTest {
mOlmAccount = new OlmAccount(); mOlmAccount = new OlmAccount();
} catch (OlmException e) { } catch (OlmException e) {
e.printStackTrace(); e.printStackTrace();
fail("OlmAccount failed " + e.getMessage()); assertTrue("OlmAccount failed " + e.getMessage(), false);
} }
assertNotNull(mOlmAccount); assertNotNull(mOlmAccount);
mOlmAccount.releaseAccount(); mOlmAccount.releaseAccount();
assertEquals(0, mOlmAccount.getOlmAccountId()); assertTrue(0 == mOlmAccount.getOlmAccountId());
} }
@Test @Test
@ -112,7 +110,7 @@ public class OlmAccountTest {
mOlmAccount = new OlmAccount(); mOlmAccount = new OlmAccount();
} catch (OlmException e) { } catch (OlmException e) {
e.printStackTrace(); e.printStackTrace();
fail("OlmAccount failed " + e.getMessage()); assertTrue("OlmAccount failed " + e.getMessage(), false);
} }
assertNotNull(mOlmAccount); assertNotNull(mOlmAccount);
mIsAccountCreated = true; mIsAccountCreated = true;
@ -136,18 +134,18 @@ public class OlmAccountTest {
try { try {
identityKeys = mOlmAccount.identityKeys(); identityKeys = mOlmAccount.identityKeys();
} catch (Exception e) { } catch (Exception e) {
fail("identityKeys failed " + e.getMessage()); assertTrue("identityKeys failed " + e.getMessage(), false);
} }
assertNotNull(identityKeys); assertNotNull(identityKeys);
Log.d(LOG_TAG,"## testIdentityKeys Keys="+identityKeys); Log.d(LOG_TAG,"## testIdentityKeys Keys="+identityKeys);
// is JSON_KEY_FINGER_PRINT_KEY present? // is JSON_KEY_FINGER_PRINT_KEY present?
String fingerPrintKey = TestHelper.getFingerprintKey(identityKeys); String fingerPrintKey = TestHelper.getFingerprintKey(identityKeys);
assertFalse("fingerprint key missing", TextUtils.isEmpty(fingerPrintKey)); assertTrue("fingerprint key missing",!TextUtils.isEmpty(fingerPrintKey));
// is JSON_KEY_IDENTITY_KEY present? // is JSON_KEY_IDENTITY_KEY present?
String identityKey = TestHelper.getIdentityKey(identityKeys); String identityKey = TestHelper.getIdentityKey(identityKeys);
assertFalse("identity key missing", TextUtils.isEmpty(identityKey)); assertTrue("identity key missing",!TextUtils.isEmpty(identityKey));
} }
//**************************************************** //****************************************************
@ -174,7 +172,7 @@ public class OlmAccountTest {
error = e.getMessage(); error = e.getMessage();
} }
assertNull(error); assertTrue(null == error);
} }
/** /**
@ -188,21 +186,21 @@ public class OlmAccountTest {
try { try {
oneTimeKeysJson = mOlmAccount.oneTimeKeys(); oneTimeKeysJson = mOlmAccount.oneTimeKeys();
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(oneTimeKeysJson); assertNotNull(oneTimeKeysJson);
try { try {
Map<String, String> map = oneTimeKeysJson.get(OlmAccount.JSON_KEY_ONE_TIME_KEY); Map<String, String> map = oneTimeKeysJson.get(OlmAccount.JSON_KEY_ONE_TIME_KEY);
assertNotNull(OlmAccount.JSON_KEY_ONE_TIME_KEY + " object is missing", map); assertTrue(OlmAccount.JSON_KEY_ONE_TIME_KEY +" object is missing", null!=map);
// test the count of the generated one time keys: // test the count of the generated one time keys:
oneTimeKeysCount = map.size(); oneTimeKeysCount = map.size();
assertEquals("Expected count=" + GENERATION_ONE_TIME_KEYS_NUMBER + " found=" + oneTimeKeysCount, GENERATION_ONE_TIME_KEYS_NUMBER, oneTimeKeysCount); assertTrue("Expected count="+GENERATION_ONE_TIME_KEYS_NUMBER+" found="+oneTimeKeysCount,GENERATION_ONE_TIME_KEYS_NUMBER==oneTimeKeysCount);
} catch (Exception e) { } catch (Exception e) {
fail("Exception MSg=" + e.getMessage()); assertTrue("Exception MSg="+e.getMessage(), false);
} }
} }
@ -212,7 +210,7 @@ public class OlmAccountTest {
try { try {
olmSession = new OlmSession(); olmSession = new OlmSession();
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception Msg=" + e.getMessage()); assertTrue("Exception Msg="+e.getMessage(), false);
} }
long sessionId = olmSession.getOlmSessionId(); long sessionId = olmSession.getOlmSessionId();
assertTrue(0 != sessionId); assertTrue(0 != sessionId);
@ -224,11 +222,11 @@ public class OlmAccountTest {
} catch (Exception e) { } catch (Exception e) {
errorMessage = e.getMessage(); errorMessage = e.getMessage();
} }
assertNotNull(errorMessage); assertTrue(null != errorMessage);
olmSession.releaseSession(); olmSession.releaseSession();
sessionId = olmSession.getOlmSessionId(); sessionId = olmSession.getOlmSessionId();
assertEquals(0, sessionId); assertTrue(0 == sessionId);
} }
@Test @Test
@ -236,7 +234,7 @@ public class OlmAccountTest {
try { try {
mOlmAccount.markOneTimeKeysAsPublished(); mOlmAccount.markOneTimeKeysAsPublished();
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
} }
@ -248,7 +246,7 @@ public class OlmAccountTest {
try { try {
signedMsg = mOlmAccount.signMessage(clearMsg); signedMsg = mOlmAccount.signMessage(clearMsg);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(signedMsg); assertNotNull(signedMsg);
@ -265,18 +263,18 @@ public class OlmAccountTest {
FileOutputStream fileOutput; FileOutputStream fileOutput;
ObjectOutputStream objectOutput; ObjectOutputStream objectOutput;
OlmAccount accountRef = null; OlmAccount accountRef = null;
OlmAccount accountDeserial; OlmAccount accountDeserial = null;
try { try {
accountRef = new OlmAccount(); accountRef = new OlmAccount();
} catch (OlmException e) { } catch (OlmException e) {
fail(e.getMessage()); assertTrue(e.getMessage(),false);
} }
try { try {
accountRef.generateOneTimeKeys(GENERATION_ONE_TIME_KEYS_NUMBER); accountRef.generateOneTimeKeys(GENERATION_ONE_TIME_KEYS_NUMBER);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(),false);
} }
// get keys references // get keys references
@ -285,7 +283,7 @@ public class OlmAccountTest {
try { try {
identityKeysRef = accountRef.identityKeys(); identityKeysRef = accountRef.identityKeys();
} catch (Exception e) { } catch (Exception e) {
fail("identityKeys failed " + e.getMessage()); assertTrue("identityKeys failed " + e.getMessage(), false);
} }
Map<String, Map<String, String>> oneTimeKeysRef = null; Map<String, Map<String, String>> oneTimeKeysRef = null;
@ -293,14 +291,14 @@ public class OlmAccountTest {
try { try {
oneTimeKeysRef = accountRef.oneTimeKeys(); oneTimeKeysRef = accountRef.oneTimeKeys();
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(identityKeysRef); assertNotNull(identityKeysRef);
assertNotNull(oneTimeKeysRef); assertNotNull(oneTimeKeysRef);
try { try {
Context context = ApplicationProvider.getApplicationContext(); Context context = getInstrumentation().getContext();
//context.getFilesDir(); //context.getFilesDir();
fileOutput = context.openFileOutput(FILE_NAME, Context.MODE_PRIVATE); fileOutput = context.openFileOutput(FILE_NAME, Context.MODE_PRIVATE);
@ -324,28 +322,32 @@ public class OlmAccountTest {
assertNotNull(oneTimeKeysDeserial); assertNotNull(oneTimeKeysDeserial);
// compare identity keys // compare identity keys
assertEquals(identityKeysDeserial.toString(), identityKeysRef.toString()); assertTrue(identityKeysDeserial.toString().equals(identityKeysRef.toString()));
// compare onetime keys // compare onetime keys
assertEquals(oneTimeKeysDeserial.toString(), oneTimeKeysRef.toString()); assertTrue(oneTimeKeysDeserial.toString().equals(oneTimeKeysRef.toString()));
accountRef.releaseAccount(); accountRef.releaseAccount();
accountDeserial.releaseAccount(); accountDeserial.releaseAccount();
} catch (FileNotFoundException e) { }
catch (FileNotFoundException e) {
Log.e(LOG_TAG, "## test13Serialization(): Exception FileNotFoundException Msg=="+e.getMessage()); Log.e(LOG_TAG, "## test13Serialization(): Exception FileNotFoundException Msg=="+e.getMessage());
fail("test13Serialization failed " + e.getMessage()); assertTrue("test13Serialization failed " + e.getMessage(), false);
} catch (ClassNotFoundException e) { }
catch (ClassNotFoundException e) {
Log.e(LOG_TAG, "## test13Serialization(): Exception ClassNotFoundException Msg==" + e.getMessage()); Log.e(LOG_TAG, "## test13Serialization(): Exception ClassNotFoundException Msg==" + e.getMessage());
fail("test13Serialization failed " + e.getMessage()); assertTrue("test13Serialization failed " + e.getMessage(), false);
} catch (IOException e) { }
catch (IOException e) {
Log.e(LOG_TAG, "## test13Serialization(): Exception IOException Msg==" + e.getMessage()); Log.e(LOG_TAG, "## test13Serialization(): Exception IOException Msg==" + e.getMessage());
fail("test13Serialization failed " + e.getMessage()); assertTrue("test13Serialization failed " + e.getMessage(), false);
} }
/*catch (OlmException e) { /*catch (OlmException e) {
Log.e(LOG_TAG, "## test13Serialization(): Exception OlmException Msg==" + e.getMessage()); Log.e(LOG_TAG, "## test13Serialization(): Exception OlmException Msg==" + e.getMessage());
}*/ catch (Exception e) { }*/
catch (Exception e) {
Log.e(LOG_TAG, "## test13Serialization(): Exception Msg==" + e.getMessage()); Log.e(LOG_TAG, "## test13Serialization(): Exception Msg==" + e.getMessage());
fail("test13Serialization failed " + e.getMessage()); assertTrue("test13Serialization failed " + e.getMessage(), false);
} }
} }
@ -365,7 +367,7 @@ public class OlmAccountTest {
errorMessage = e.getMessage(); errorMessage = e.getMessage();
} }
assertNull(errorMessage); assertTrue(null == errorMessage);
// keys number = negative value // keys number = negative value
errorMessage = null; errorMessage = null;
@ -375,7 +377,7 @@ public class OlmAccountTest {
errorMessage = e.getMessage(); errorMessage = e.getMessage();
} }
assertNotNull(errorMessage); assertTrue(null != errorMessage);
} }
@Test @Test
@ -384,13 +386,13 @@ public class OlmAccountTest {
try { try {
olmAccount = new OlmAccount(); olmAccount = new OlmAccount();
} catch (OlmException e) { } catch (OlmException e) {
fail(e.getMessage()); assertTrue(e.getMessage(),false);
} }
try { try {
olmAccount.removeOneTimeKeys(null); olmAccount.removeOneTimeKeys(null);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
olmAccount.releaseAccount(); olmAccount.releaseAccount();
@ -402,7 +404,7 @@ public class OlmAccountTest {
try { try {
olmAccount = new OlmAccount(); olmAccount = new OlmAccount();
} catch (OlmException e) { } catch (OlmException e) {
fail(e.getMessage()); assertTrue(e.getMessage(),false);
} }
String signedMsg = null; String signedMsg = null;
@ -447,31 +449,31 @@ public class OlmAccountTest {
String identityKey1 = TestHelper.getIdentityKey(identityKeys1); String identityKey1 = TestHelper.getIdentityKey(identityKeys1);
String identityKey2 = TestHelper.getIdentityKey(identityKeys2); String identityKey2 = TestHelper.getIdentityKey(identityKeys2);
assertNotEquals(identityKey1, identityKey2); assertFalse(identityKey1.equals(identityKey2));
String identityKey3 = TestHelper.getIdentityKey(identityKeys3); String identityKey3 = TestHelper.getIdentityKey(identityKeys3);
assertNotEquals(identityKey2, identityKey3); assertFalse(identityKey2.equals(identityKey3));
String identityKey4 = TestHelper.getIdentityKey(identityKeys4); String identityKey4 = TestHelper.getIdentityKey(identityKeys4);
assertNotEquals(identityKey3, identityKey4); assertFalse(identityKey3.equals(identityKey4));
String identityKey5 = TestHelper.getIdentityKey(identityKeys5); String identityKey5 = TestHelper.getIdentityKey(identityKeys5);
assertNotEquals(identityKey4, identityKey5); assertFalse(identityKey4.equals(identityKey5));
String identityKey6 = TestHelper.getIdentityKey(identityKeys6); String identityKey6 = TestHelper.getIdentityKey(identityKeys6);
assertNotEquals(identityKey5, identityKey6); assertFalse(identityKey5.equals(identityKey6));
String identityKey7 = TestHelper.getIdentityKey(identityKeys7); String identityKey7 = TestHelper.getIdentityKey(identityKeys7);
assertNotEquals(identityKey6, identityKey7); assertFalse(identityKey6.equals(identityKey7));
String identityKey8 = TestHelper.getIdentityKey(identityKeys8); String identityKey8 = TestHelper.getIdentityKey(identityKeys8);
assertNotEquals(identityKey7, identityKey8); assertFalse(identityKey7.equals(identityKey8));
String identityKey9 = TestHelper.getIdentityKey(identityKeys9); String identityKey9 = TestHelper.getIdentityKey(identityKeys9);
assertNotEquals(identityKey8, identityKey9); assertFalse(identityKey8.equals(identityKey9));
String identityKey10 = TestHelper.getIdentityKey(identityKeys10); String identityKey10 = TestHelper.getIdentityKey(identityKeys10);
assertNotEquals(identityKey9, identityKey10); assertFalse(identityKey9.equals(identityKey10));
account1.releaseAccount(); account1.releaseAccount();
account2.releaseAccount(); account2.releaseAccount();
@ -485,22 +487,7 @@ public class OlmAccountTest {
account10.releaseAccount(); account10.releaseAccount();
} catch (OlmException e) { } catch (OlmException e) {
fail(e.getMessage()); assertTrue(e.getMessage(),false);
}
}
@Test
public void test18GenerateFallbackKey() {
try {
OlmAccount account1 = new OlmAccount();
account1.generateFallbackKey();
Map<String, Map<String, String>> fallbackKeyMap = account1.fallbackKey();
assertNotNull(fallbackKeyMap);
assertEquals(1, fallbackKeyMap.size());
} catch (OlmException e) {
fail(e.getMessage());
} }
} }
} }

View file

@ -18,12 +18,10 @@
package org.matrix.olm; package org.matrix.olm;
import android.content.Context; import android.content.Context;
import android.support.test.runner.AndroidJUnit4;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.FixMethodOrder; import org.junit.FixMethodOrder;
import org.junit.Test; import org.junit.Test;
@ -38,12 +36,10 @@ import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import static org.junit.Assert.assertEquals; import static android.support.test.InstrumentationRegistry.getInstrumentation;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING) @FixMethodOrder(MethodSorters.NAME_ASCENDING)
@ -87,7 +83,7 @@ public class OlmGroupSessionTest {
try { try {
mAliceOutboundGroupSession = new OlmOutboundGroupSession(); mAliceOutboundGroupSession = new OlmOutboundGroupSession();
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception in OlmOutboundGroupSession, Exception code=" + e.getExceptionCode()); assertTrue("Exception in OlmOutboundGroupSession, Exception code=" + e.getExceptionCode(), false);
} }
} }
@ -99,7 +95,7 @@ public class OlmGroupSessionTest {
try { try {
mAliceSessionIdentifier = mAliceOutboundGroupSession.sessionIdentifier(); mAliceSessionIdentifier = mAliceOutboundGroupSession.sessionIdentifier();
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(mAliceSessionIdentifier); assertNotNull(mAliceSessionIdentifier);
@ -114,7 +110,7 @@ public class OlmGroupSessionTest {
try { try {
mAliceOutboundSessionKey = mAliceOutboundGroupSession.sessionKey(); mAliceOutboundSessionKey = mAliceOutboundGroupSession.sessionKey();
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(mAliceOutboundSessionKey); assertNotNull(mAliceOutboundSessionKey);
assertTrue(mAliceOutboundSessionKey.length() > 0); assertTrue(mAliceOutboundSessionKey.length() > 0);
@ -124,7 +120,7 @@ public class OlmGroupSessionTest {
public void test04GetOutboundGroupMessageIndex() { public void test04GetOutboundGroupMessageIndex() {
// test message index before any encryption // test message index before any encryption
mAliceMessageIndex = mAliceOutboundGroupSession.messageIndex(); mAliceMessageIndex = mAliceOutboundGroupSession.messageIndex();
assertEquals(0, mAliceMessageIndex); assertTrue(0 == mAliceMessageIndex);
} }
@Test @Test
@ -133,13 +129,13 @@ public class OlmGroupSessionTest {
try { try {
mAliceToBobMessage = mAliceOutboundGroupSession.encryptMessage(CLEAR_MESSAGE1); mAliceToBobMessage = mAliceOutboundGroupSession.encryptMessage(CLEAR_MESSAGE1);
} catch (Exception e) { } catch (Exception e) {
fail("Exception in bob encryptMessage, Exception code=" + e.getMessage()); assertTrue("Exception in bob encryptMessage, Exception code=" + e.getMessage(), false);
} }
assertFalse(TextUtils.isEmpty(mAliceToBobMessage)); assertFalse(TextUtils.isEmpty(mAliceToBobMessage));
// test message index after encryption is incremented // test message index after encryption is incremented
mAliceMessageIndex = mAliceOutboundGroupSession.messageIndex(); mAliceMessageIndex = mAliceOutboundGroupSession.messageIndex();
assertEquals(1, mAliceMessageIndex); assertTrue(1 == mAliceMessageIndex);
} }
@Test @Test
@ -148,7 +144,7 @@ public class OlmGroupSessionTest {
try { try {
mBobInboundGroupSession = new OlmInboundGroupSession(mAliceOutboundSessionKey); mBobInboundGroupSession = new OlmInboundGroupSession(mAliceOutboundSessionKey);
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception in bob OlmInboundGroupSession, Exception code=" + e.getExceptionCode()); assertTrue("Exception in bob OlmInboundGroupSession, Exception code=" + e.getExceptionCode(), false);
} }
} }
@ -160,7 +156,7 @@ public class OlmGroupSessionTest {
try { try {
mBobSessionIdentifier = mBobInboundGroupSession.sessionIdentifier(); mBobSessionIdentifier = mBobInboundGroupSession.sessionIdentifier();
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertFalse(TextUtils.isEmpty(mBobSessionIdentifier)); assertFalse(TextUtils.isEmpty(mBobSessionIdentifier));
} }
@ -168,7 +164,7 @@ public class OlmGroupSessionTest {
@Test @Test
public void test09SessionIdentifiersAreIdentical() { public void test09SessionIdentifiersAreIdentical() {
// check both session identifiers are equals: alice vs bob // check both session identifiers are equals: alice vs bob
assertEquals(mAliceSessionIdentifier, mBobSessionIdentifier); assertTrue(mAliceSessionIdentifier.equals(mBobSessionIdentifier));
} }
@Test @Test
@ -179,19 +175,19 @@ public class OlmGroupSessionTest {
try { try {
result = mBobInboundGroupSession.decryptMessage(mAliceToBobMessage); result = mBobInboundGroupSession.decryptMessage(mAliceToBobMessage);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
// test decrypted message // test decrypted message
mBobDecryptedMessage = result.mDecryptedMessage; mBobDecryptedMessage = result.mDecryptedMessage;
assertFalse(TextUtils.isEmpty(mBobDecryptedMessage)); assertFalse(TextUtils.isEmpty(mBobDecryptedMessage));
assertEquals(0, result.mIndex); assertTrue(0 == result.mIndex);
} }
@Test @Test
public void test11InboundDecryptedMessageIdentical() { public void test11InboundDecryptedMessageIdentical() {
// test decrypted message // test decrypted message
assertEquals(mBobDecryptedMessage, CLEAR_MESSAGE1); assertTrue(mBobDecryptedMessage.equals(CLEAR_MESSAGE1));
} }
@Test @Test
@ -221,13 +217,13 @@ public class OlmGroupSessionTest {
try { try {
outboundGroupSessionRef = new OlmOutboundGroupSession(); outboundGroupSessionRef = new OlmOutboundGroupSession();
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception in OlmOutboundGroupSession, Exception code=" + e.getExceptionCode()); assertTrue("Exception in OlmOutboundGroupSession, Exception code=" + e.getExceptionCode(), false);
} }
assertNotNull(outboundGroupSessionRef); assertNotNull(outboundGroupSessionRef);
// serialize alice session // serialize alice session
Context context = ApplicationProvider.getApplicationContext(); Context context = getInstrumentation().getContext();
try { try {
FileOutputStream fileOutput = context.openFileOutput(FILE_NAME_SERIAL_OUT_SESSION, Context.MODE_PRIVATE); FileOutputStream fileOutput = context.openFileOutput(FILE_NAME_SERIAL_OUT_SESSION, Context.MODE_PRIVATE);
ObjectOutputStream objectOutput = new ObjectOutputStream(fileOutput); ObjectOutputStream objectOutput = new ObjectOutputStream(fileOutput);
@ -249,7 +245,7 @@ public class OlmGroupSessionTest {
assertFalse(TextUtils.isEmpty(sessionKeySerial)); assertFalse(TextUtils.isEmpty(sessionKeySerial));
// session keys comparison // session keys comparison
assertEquals(sessionKeyRef, sessionKeySerial); assertTrue(sessionKeyRef.equals(sessionKeySerial));
// get sessions IDs // get sessions IDs
String sessionIdRef = outboundGroupSessionRef.sessionIdentifier(); String sessionIdRef = outboundGroupSessionRef.sessionIdentifier();
@ -258,7 +254,7 @@ public class OlmGroupSessionTest {
assertFalse(TextUtils.isEmpty(sessionIdSerial)); assertFalse(TextUtils.isEmpty(sessionIdSerial));
// session IDs comparison // session IDs comparison
assertEquals(sessionIdRef, sessionIdSerial); assertTrue(sessionIdRef.equals(sessionIdSerial));
outboundGroupSessionRef.releaseSession(); outboundGroupSessionRef.releaseSession();
outboundGroupSessionSerial.releaseSession(); outboundGroupSessionSerial.releaseSession();
@ -267,19 +263,19 @@ public class OlmGroupSessionTest {
assertTrue(outboundGroupSessionSerial.isReleased()); assertTrue(outboundGroupSessionSerial.isReleased());
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Log.e(LOG_TAG, "## test15SerializeOutboundSession(): Exception FileNotFoundException Msg=="+e.getMessage()); Log.e(LOG_TAG, "## test15SerializeOutboundSession(): Exception FileNotFoundException Msg=="+e.getMessage());
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
Log.e(LOG_TAG, "## test15SerializeOutboundSession(): Exception ClassNotFoundException Msg==" + e.getMessage()); Log.e(LOG_TAG, "## test15SerializeOutboundSession(): Exception ClassNotFoundException Msg==" + e.getMessage());
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} catch (OlmException e) { } catch (OlmException e) {
Log.e(LOG_TAG, "## test15SerializeOutboundSession(): Exception OlmException Msg==" + e.getMessage()); Log.e(LOG_TAG, "## test15SerializeOutboundSession(): Exception OlmException Msg==" + e.getMessage());
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} catch (IOException e) { } catch (IOException e) {
Log.e(LOG_TAG, "## test15SerializeOutboundSession(): Exception IOException Msg==" + e.getMessage()); Log.e(LOG_TAG, "## test15SerializeOutboundSession(): Exception IOException Msg==" + e.getMessage());
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} catch (Exception e) { } catch (Exception e) {
Log.e(LOG_TAG, "## test15SerializeOutboundSession(): Exception Msg==" + e.getMessage()); Log.e(LOG_TAG, "## test15SerializeOutboundSession(): Exception Msg==" + e.getMessage());
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
} }
@ -293,7 +289,7 @@ public class OlmGroupSessionTest {
try { try {
aliceOutboundGroupSession = new OlmOutboundGroupSession(); aliceOutboundGroupSession = new OlmOutboundGroupSession();
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception in OlmOutboundGroupSession, Exception code=" + e.getExceptionCode()); assertTrue("Exception in OlmOutboundGroupSession, Exception code=" + e.getExceptionCode(), false);
} }
assertNotNull(aliceOutboundGroupSession); assertNotNull(aliceOutboundGroupSession);
@ -303,7 +299,7 @@ public class OlmGroupSessionTest {
try { try {
sessionKeyRef = aliceOutboundGroupSession.sessionKey(); sessionKeyRef = aliceOutboundGroupSession.sessionKey();
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(sessionKeyRef); assertNotNull(sessionKeyRef);
@ -311,12 +307,12 @@ public class OlmGroupSessionTest {
try { try {
bobInboundGroupSessionRef = new OlmInboundGroupSession(sessionKeyRef); bobInboundGroupSessionRef = new OlmInboundGroupSession(sessionKeyRef);
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception in OlmInboundGroupSession, Exception code=" + e.getExceptionCode()); assertTrue("Exception in OlmInboundGroupSession, Exception code=" + e.getExceptionCode(), false);
} }
assertNotNull(bobInboundGroupSessionRef); assertNotNull(bobInboundGroupSessionRef);
// serialize alice session // serialize alice session
Context context = ApplicationProvider.getApplicationContext(); Context context = getInstrumentation().getContext();
try { try {
FileOutputStream fileOutput = context.openFileOutput(FILE_NAME_SERIAL_IN_SESSION, Context.MODE_PRIVATE); FileOutputStream fileOutput = context.openFileOutput(FILE_NAME_SERIAL_IN_SESSION, Context.MODE_PRIVATE);
ObjectOutputStream objectOutput = new ObjectOutputStream(fileOutput); ObjectOutputStream objectOutput = new ObjectOutputStream(fileOutput);
@ -340,8 +336,8 @@ public class OlmGroupSessionTest {
assertFalse(TextUtils.isEmpty(sessionIdSerial)); assertFalse(TextUtils.isEmpty(sessionIdSerial));
// session IDs comparison // session IDs comparison
assertEquals(aliceSessionId, sessionIdSerial); assertTrue(aliceSessionId.equals(sessionIdSerial));
assertEquals(sessionIdRef, sessionIdSerial); assertTrue(sessionIdRef.equals(sessionIdSerial));
aliceOutboundGroupSession.releaseSession(); aliceOutboundGroupSession.releaseSession();
bobInboundGroupSessionRef.releaseSession(); bobInboundGroupSessionRef.releaseSession();
@ -352,19 +348,19 @@ public class OlmGroupSessionTest {
assertTrue(bobInboundGroupSessionSerial.isReleased()); assertTrue(bobInboundGroupSessionSerial.isReleased());
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Log.e(LOG_TAG, "## test16SerializeInboundSession(): Exception FileNotFoundException Msg=="+e.getMessage()); Log.e(LOG_TAG, "## test16SerializeInboundSession(): Exception FileNotFoundException Msg=="+e.getMessage());
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
Log.e(LOG_TAG, "## test16SerializeInboundSession(): Exception ClassNotFoundException Msg==" + e.getMessage()); Log.e(LOG_TAG, "## test16SerializeInboundSession(): Exception ClassNotFoundException Msg==" + e.getMessage());
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} catch (OlmException e) { } catch (OlmException e) {
Log.e(LOG_TAG, "## test16SerializeInboundSession(): Exception OlmException Msg==" + e.getMessage()); Log.e(LOG_TAG, "## test16SerializeInboundSession(): Exception OlmException Msg==" + e.getMessage());
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} catch (IOException e) { } catch (IOException e) {
Log.e(LOG_TAG, "## test16SerializeInboundSession(): Exception IOException Msg==" + e.getMessage()); Log.e(LOG_TAG, "## test16SerializeInboundSession(): Exception IOException Msg==" + e.getMessage());
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} catch (Exception e) { } catch (Exception e) {
Log.e(LOG_TAG, "## test16SerializeInboundSession(): Exception Msg==" + e.getMessage()); Log.e(LOG_TAG, "## test16SerializeInboundSession(): Exception Msg==" + e.getMessage());
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
} }
@ -396,48 +392,48 @@ public class OlmGroupSessionTest {
// get the session key from the outbound group sessions // get the session key from the outbound group sessions
String sessionKey1 = outboundGroupSession1.sessionKey(); String sessionKey1 = outboundGroupSession1.sessionKey();
String sessionKey2 = outboundGroupSession2.sessionKey(); String sessionKey2 = outboundGroupSession2.sessionKey();
assertNotEquals(sessionKey1, sessionKey2); assertFalse(sessionKey1.equals(sessionKey2));
String sessionKey3 = outboundGroupSession3.sessionKey(); String sessionKey3 = outboundGroupSession3.sessionKey();
assertNotEquals(sessionKey2, sessionKey3); assertFalse(sessionKey2.equals(sessionKey3));
String sessionKey4 = outboundGroupSession4.sessionKey(); String sessionKey4 = outboundGroupSession4.sessionKey();
assertNotEquals(sessionKey3, sessionKey4); assertFalse(sessionKey3.equals(sessionKey4));
String sessionKey5 = outboundGroupSession5.sessionKey(); String sessionKey5 = outboundGroupSession5.sessionKey();
assertNotEquals(sessionKey4, sessionKey5); assertFalse(sessionKey4.equals(sessionKey5));
String sessionKey6 = outboundGroupSession6.sessionKey(); String sessionKey6 = outboundGroupSession6.sessionKey();
assertNotEquals(sessionKey5, sessionKey6); assertFalse(sessionKey5.equals(sessionKey6));
String sessionKey7 = outboundGroupSession7.sessionKey(); String sessionKey7 = outboundGroupSession7.sessionKey();
assertNotEquals(sessionKey6, sessionKey7); assertFalse(sessionKey6.equals(sessionKey7));
String sessionKey8 = outboundGroupSession8.sessionKey(); String sessionKey8 = outboundGroupSession8.sessionKey();
assertNotEquals(sessionKey7, sessionKey8); assertFalse(sessionKey7.equals(sessionKey8));
// get the session IDs from the outbound group sessions // get the session IDs from the outbound group sessions
String sessionId1 = outboundGroupSession1.sessionIdentifier(); String sessionId1 = outboundGroupSession1.sessionIdentifier();
String sessionId2 = outboundGroupSession2.sessionIdentifier(); String sessionId2 = outboundGroupSession2.sessionIdentifier();
assertNotEquals(sessionId1, sessionId2); assertFalse(sessionId1.equals(sessionId2));
String sessionId3 = outboundGroupSession3.sessionKey(); String sessionId3 = outboundGroupSession3.sessionKey();
assertNotEquals(sessionId2, sessionId3); assertFalse(sessionId2.equals(sessionId3));
String sessionId4 = outboundGroupSession4.sessionKey(); String sessionId4 = outboundGroupSession4.sessionKey();
assertNotEquals(sessionId3, sessionId4); assertFalse(sessionId3.equals(sessionId4));
String sessionId5 = outboundGroupSession5.sessionKey(); String sessionId5 = outboundGroupSession5.sessionKey();
assertNotEquals(sessionId4, sessionId5); assertFalse(sessionId4.equals(sessionId5));
String sessionId6 = outboundGroupSession6.sessionKey(); String sessionId6 = outboundGroupSession6.sessionKey();
assertNotEquals(sessionId5, sessionId6); assertFalse(sessionId5.equals(sessionId6));
String sessionId7 = outboundGroupSession7.sessionKey(); String sessionId7 = outboundGroupSession7.sessionKey();
assertNotEquals(sessionId6, sessionId7); assertFalse(sessionId6.equals(sessionId7));
String sessionId8 = outboundGroupSession8.sessionKey(); String sessionId8 = outboundGroupSession8.sessionKey();
assertNotEquals(sessionId7, sessionId8); assertFalse(sessionId7.equals(sessionId8));
outboundGroupSession1.releaseSession(); outboundGroupSession1.releaseSession();
outboundGroupSession2.releaseSession(); outboundGroupSession2.releaseSession();
@ -457,7 +453,7 @@ public class OlmGroupSessionTest {
assertTrue(outboundGroupSession7.isReleased()); assertTrue(outboundGroupSession7.isReleased());
assertTrue(outboundGroupSession8.isReleased()); assertTrue(outboundGroupSession8.isReleased());
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception in OlmOutboundGroupSession, Exception code=" + e.getExceptionCode()); assertTrue("Exception in OlmOutboundGroupSession, Exception code=" + e.getExceptionCode(), false);
} }
} }
@ -480,7 +476,7 @@ public class OlmGroupSessionTest {
try { try {
bobInboundGroupSession = new OlmInboundGroupSession(sessionKeyRef); bobInboundGroupSession = new OlmInboundGroupSession(sessionKeyRef);
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception in test18TestBadCharacterCrashInDecrypt, Exception code=" + e.getExceptionCode()); assertTrue("Exception in test18TestBadCharacterCrashInDecrypt, Exception code=" + e.getExceptionCode(), false);
} }
OlmInboundGroupSession.DecryptMessageResult result = null; OlmInboundGroupSession.DecryptMessageResult result = null;
@ -488,11 +484,11 @@ public class OlmGroupSessionTest {
try { try {
result = bobInboundGroupSession.decryptMessage(msgToDecryptWithEmoji); result = bobInboundGroupSession.decryptMessage(msgToDecryptWithEmoji);
} catch (Exception e) { } catch (Exception e) {
fail("Exception in test18TestBadCharacterCrashInDecrypt, Exception code=" + e.getMessage()); assertTrue("Exception in test18TestBadCharacterCrashInDecrypt, Exception code=" + e.getMessage(), false);
} }
assertNotNull(result.mDecryptedMessage); assertNotNull(result.mDecryptedMessage);
assertEquals(13, result.mIndex); assertTrue(13 == result.mIndex);
} }
/** /**
@ -512,7 +508,7 @@ public class OlmGroupSessionTest {
try { try {
bobInboundGroupSession = new OlmInboundGroupSession(sessionKeyRef); bobInboundGroupSession = new OlmInboundGroupSession(sessionKeyRef);
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception in test19TestErrorMessageReturnedInDecrypt, Exception code=" + e.getExceptionCode()); assertTrue("Exception in test19TestErrorMessageReturnedInDecrypt, Exception code=" + e.getExceptionCode(), false);
} }
String exceptionMessage = null; String exceptionMessage = null;
@ -522,7 +518,8 @@ public class OlmGroupSessionTest {
exceptionMessage = e.getMessage(); exceptionMessage = e.getMessage();
} }
assertEquals(EXPECTED_ERROR_MESSAGE, exceptionMessage); assertTrue(0!=EXPECTED_ERROR_MESSAGE.length());
assertTrue(EXPECTED_ERROR_MESSAGE.equals(exceptionMessage));
} }
@ -547,7 +544,7 @@ public class OlmGroupSessionTest {
try { try {
inboundGroupSession = new OlmInboundGroupSession(sessionKey); inboundGroupSession = new OlmInboundGroupSession(sessionKey);
} catch (Exception e) { } catch (Exception e) {
fail("OlmInboundGroupSession failed " + e.getMessage()); assertTrue("OlmInboundGroupSession failed " + e.getMessage(), false);
} }
boolean isVerified = false; boolean isVerified = false;
@ -555,7 +552,7 @@ public class OlmGroupSessionTest {
try { try {
isVerified = inboundGroupSession.isVerified(); isVerified = inboundGroupSession.isVerified();
} catch (Exception e) { } catch (Exception e) {
fail("isVerified failed " + e.getMessage()); assertTrue("isVerified failed " + e.getMessage(), false);
} }
assertTrue(isVerified); assertTrue(isVerified);
@ -565,26 +562,26 @@ public class OlmGroupSessionTest {
try { try {
result = inboundGroupSession.decryptMessage(message); result = inboundGroupSession.decryptMessage(message);
} catch (Exception e) { } catch (Exception e) {
fail("decryptMessage failed " + e.getMessage()); assertTrue("decryptMessage failed " + e.getMessage(), false);
} }
assertTrue(TextUtils.equals(result.mDecryptedMessage, "Message")); assertTrue(TextUtils.equals(result.mDecryptedMessage, "Message"));
assertEquals(0, result.mIndex); assertTrue(0 == result.mIndex);
String export = null; String export = null;
try { try {
export = inboundGroupSession.export(0); export = inboundGroupSession.export(0);
} catch (Exception e) { } catch (Exception e) {
fail("export failed " + e.getMessage()); assertTrue("export failed " + e.getMessage(), false);
} }
assertFalse(TextUtils.isEmpty(export)); assertTrue(!TextUtils.isEmpty(export));
long index = -1; long index = -1;
try { try {
index = inboundGroupSession.getFirstKnownIndex(); index = inboundGroupSession.getFirstKnownIndex();
} catch (Exception e) { } catch (Exception e) {
fail("getFirstKnownIndex failed " + e.getMessage()); assertTrue("getFirstKnownIndex failed " + e.getMessage(), false);
} }
assertTrue(index >=0); assertTrue(index >=0);
@ -596,13 +593,13 @@ public class OlmGroupSessionTest {
try { try {
inboundGroupSession2 = inboundGroupSession.importSession(export); inboundGroupSession2 = inboundGroupSession.importSession(export);
} catch (Exception e) { } catch (Exception e) {
fail("OlmInboundGroupSession failed " + e.getMessage()); assertTrue("OlmInboundGroupSession failed " + e.getMessage(), false);
} }
try { try {
isVerified = inboundGroupSession2.isVerified(); isVerified = inboundGroupSession2.isVerified();
} catch (Exception e) { } catch (Exception e) {
fail("isVerified failed " + e.getMessage()); assertTrue("isVerified failed " + e.getMessage(), false);
} }
assertFalse(isVerified); assertFalse(isVerified);
@ -611,16 +608,16 @@ public class OlmGroupSessionTest {
try { try {
result = inboundGroupSession2.decryptMessage(message); result = inboundGroupSession2.decryptMessage(message);
} catch (Exception e) { } catch (Exception e) {
fail("decryptMessage failed " + e.getMessage()); assertTrue("decryptMessage failed " + e.getMessage(), false);
} }
assertTrue(TextUtils.equals(result.mDecryptedMessage, "Message")); assertTrue(TextUtils.equals(result.mDecryptedMessage, "Message"));
assertEquals(0, result.mIndex); assertTrue(0 == result.mIndex);
try { try {
isVerified = inboundGroupSession2.isVerified(); isVerified = inboundGroupSession2.isVerified();
} catch (Exception e) { } catch (Exception e) {
fail("isVerified failed " + e.getMessage()); assertTrue("isVerified failed " + e.getMessage(), false);
} }
assertTrue(isVerified); assertTrue(isVerified);

View file

@ -16,22 +16,21 @@
package org.matrix.olm; package org.matrix.olm;
import android.support.test.runner.AndroidJUnit4;
import android.util.Log; import android.util.Log;
import androidx.test.ext.junit.runners.AndroidJUnit4; import java.util.Arrays;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder; import org.junit.FixMethodOrder;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters; import org.junit.runners.MethodSorters;
import java.util.Arrays; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING) @FixMethodOrder(MethodSorters.NAME_ASCENDING)
@ -48,13 +47,13 @@ public class OlmPkTest {
mOlmPkEncryption = new OlmPkEncryption(); mOlmPkEncryption = new OlmPkEncryption();
} catch (OlmException e) { } catch (OlmException e) {
e.printStackTrace(); e.printStackTrace();
fail("OlmPkEncryption failed " + e.getMessage()); assertTrue("OlmPkEncryption failed " + e.getMessage(), false);
} }
try { try {
mOlmPkDecryption = new OlmPkDecryption(); mOlmPkDecryption = new OlmPkDecryption();
} catch (OlmException e) { } catch (OlmException e) {
e.printStackTrace(); e.printStackTrace();
fail("OlmPkEncryption failed " + e.getMessage()); assertTrue("OlmPkEncryption failed " + e.getMessage(), false);
} }
assertNotNull(mOlmPkEncryption); assertNotNull(mOlmPkEncryption);
@ -64,13 +63,13 @@ public class OlmPkTest {
try { try {
key = mOlmPkDecryption.generateKey(); key = mOlmPkDecryption.generateKey();
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception in generateKey, Exception code=" + e.getExceptionCode()); assertTrue("Exception in generateKey, Exception code=" + e.getExceptionCode(), false);
} }
Log.d(LOG_TAG, "Ephemeral Key: " + key); Log.d(LOG_TAG, "Ephemeral Key: " + key);
try { try {
mOlmPkEncryption.setRecipientKey(key); mOlmPkEncryption.setRecipientKey(key);
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception in setRecipientKey, Exception code=" + e.getExceptionCode()); assertTrue("Exception in setRecipientKey, Exception code=" + e.getExceptionCode(), false);
} }
String clearMessage = "Public key test"; String clearMessage = "Public key test";
@ -78,7 +77,7 @@ public class OlmPkTest {
try { try {
message = mOlmPkEncryption.encrypt(clearMessage); message = mOlmPkEncryption.encrypt(clearMessage);
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception in encrypt, Exception code=" + e.getExceptionCode()); assertTrue("Exception in encrypt, Exception code=" + e.getExceptionCode(), false);
} }
Log.d(LOG_TAG, "message: " + message.mCipherText + " " + message.mMac + " " + message.mEphemeralKey); Log.d(LOG_TAG, "message: " + message.mCipherText + " " + message.mMac + " " + message.mEphemeralKey);
@ -86,9 +85,9 @@ public class OlmPkTest {
try { try {
decryptedMessage = mOlmPkDecryption.decrypt(message); decryptedMessage = mOlmPkDecryption.decrypt(message);
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception in decrypt, Exception code=" + e.getExceptionCode()); assertTrue("Exception in decrypt, Exception code=" + e.getExceptionCode(), false);
} }
assertEquals(clearMessage, decryptedMessage); assertTrue(clearMessage.equals(decryptedMessage));
mOlmPkEncryption.releaseEncryption(); mOlmPkEncryption.releaseEncryption();
mOlmPkDecryption.releaseDecryption(); mOlmPkDecryption.releaseDecryption();
@ -102,7 +101,7 @@ public class OlmPkTest {
mOlmPkDecryption = new OlmPkDecryption(); mOlmPkDecryption = new OlmPkDecryption();
} catch (OlmException e) { } catch (OlmException e) {
e.printStackTrace(); e.printStackTrace();
fail("OlmPkEncryption failed " + e.getMessage()); assertTrue("OlmPkEncryption failed " + e.getMessage(), false);
} }
assertNotNull(mOlmPkDecryption); assertNotNull(mOlmPkDecryption);
@ -118,12 +117,12 @@ public class OlmPkTest {
(byte)0x1D, (byte)0xB9, (byte)0x2C, (byte)0x2A (byte)0x1D, (byte)0xB9, (byte)0x2C, (byte)0x2A
}; };
assertEquals(privateKey.length, OlmPkDecryption.privateKeyLength()); assertTrue(privateKey.length == OlmPkDecryption.privateKeyLength());
try { try {
mOlmPkDecryption.setPrivateKey(privateKey); mOlmPkDecryption.setPrivateKey(privateKey);
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception in setPrivateKey, Exception code=" + e.getExceptionCode()); assertTrue("Exception in setPrivateKey, Exception code=" + e.getExceptionCode(), false);
} }
byte[] privateKeyCopy = null; byte[] privateKeyCopy = null;
@ -131,10 +130,10 @@ public class OlmPkTest {
try { try {
privateKeyCopy = mOlmPkDecryption.privateKey(); privateKeyCopy = mOlmPkDecryption.privateKey();
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception in privateKey, Exception code=" + e.getExceptionCode()); assertTrue("Exception in privateKey, Exception code=" + e.getExceptionCode(), false);
} }
assertArrayEquals(privateKey, privateKeyCopy); assertTrue(Arrays.equals(privateKey, privateKeyCopy));
mOlmPkDecryption.releaseDecryption(); mOlmPkDecryption.releaseDecryption();
assertTrue(mOlmPkDecryption.isReleased()); assertTrue(mOlmPkDecryption.isReleased());
@ -146,7 +145,7 @@ public class OlmPkTest {
mOlmPkSigning = new OlmPkSigning(); mOlmPkSigning = new OlmPkSigning();
} catch (OlmException e) { } catch (OlmException e) {
e.printStackTrace(); e.printStackTrace();
fail("OlmPkSigning failed " + e.getMessage()); assertTrue("OlmPkSigning failed " + e.getMessage(), false);
} }
assertNotNull(mOlmPkSigning); assertNotNull(mOlmPkSigning);
@ -156,17 +155,17 @@ public class OlmPkTest {
seed = OlmPkSigning.generateSeed(); seed = OlmPkSigning.generateSeed();
} catch (OlmException e) { } catch (OlmException e) {
e.printStackTrace(); e.printStackTrace();
fail("generateSeed failed " + e.getMessage()); assertTrue("generateSeed failed " + e.getMessage(), false);
} }
assertEquals(seed.length, OlmPkSigning.seedLength()); assertTrue(seed.length == OlmPkSigning.seedLength());
String pubkey = null; String pubkey = null;
try { try {
pubkey = mOlmPkSigning.initWithSeed(seed); pubkey = mOlmPkSigning.initWithSeed(seed);
} catch (OlmException e) { } catch (OlmException e) {
e.printStackTrace(); e.printStackTrace();
fail("initWithSeed failed " + e.getMessage()); assertTrue("initWithSeed failed " + e.getMessage(), false);
} }
String message = "We hold these truths to be self-evident, that all men are created equal, that they are endowed by their Creator with certain unalienable Rights, that among these are Life, Liberty and the pursuit of Happiness."; String message = "We hold these truths to be self-evident, that all men are created equal, that they are endowed by their Creator with certain unalienable Rights, that among these are Life, Liberty and the pursuit of Happiness.";
@ -176,7 +175,7 @@ public class OlmPkTest {
signature = mOlmPkSigning.sign(message); signature = mOlmPkSigning.sign(message);
} catch (OlmException e) { } catch (OlmException e) {
e.printStackTrace(); e.printStackTrace();
fail("sign failed " + e.getMessage()); assertTrue("sign failed " + e.getMessage(), false);
} }
OlmUtility olmUtility = null; OlmUtility olmUtility = null;
@ -184,14 +183,14 @@ public class OlmPkTest {
olmUtility = new OlmUtility(); olmUtility = new OlmUtility();
} catch (OlmException e) { } catch (OlmException e) {
e.printStackTrace(); e.printStackTrace();
fail("olmUtility failed " + e.getMessage()); assertTrue("olmUtility failed " + e.getMessage(), false);
} }
try { try {
olmUtility.verifyEd25519Signature(signature, pubkey, message); olmUtility.verifyEd25519Signature(signature, pubkey, message);
} catch (OlmException e) { } catch (OlmException e) {
e.printStackTrace(); e.printStackTrace();
fail("Signature verification failed " + e.getMessage()); assertTrue("Signature verification failed " + e.getMessage(), false);
} }
mOlmPkSigning.releaseSigning(); mOlmPkSigning.releaseSigning();

View file

@ -16,9 +16,9 @@
package org.matrix.olm; package org.matrix.olm;
import android.util.Log;
import androidx.test.ext.junit.runners.AndroidJUnit4; import android.support.test.runner.AndroidJUnit4;
import android.util.Log;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.FixMethodOrder; import org.junit.FixMethodOrder;
@ -29,7 +29,6 @@ import org.junit.runners.MethodSorters;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING) @FixMethodOrder(MethodSorters.NAME_ASCENDING)
@ -92,7 +91,7 @@ public class OlmSasTest {
} catch (Exception e) { } catch (Exception e) {
fail("OlmSas init failed " + e.getMessage()); assertTrue("OlmSas init failed " + e.getMessage(), false);
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
if (aliceSas != null) { if (aliceSas != null) {

View file

@ -18,12 +18,11 @@
package org.matrix.olm; package org.matrix.olm;
import android.content.Context; import android.content.Context;
import android.support.test.runner.AndroidJUnit4;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import androidx.test.core.app.ApplicationProvider; import org.json.JSONObject;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.FixMethodOrder; import org.junit.FixMethodOrder;
import org.junit.Test; import org.junit.Test;
@ -38,12 +37,10 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.util.Map; import java.util.Map;
import static org.junit.Assert.assertEquals; import static android.support.test.InstrumentationRegistry.getInstrumentation;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING) @FixMethodOrder(MethodSorters.NAME_ASCENDING)
@ -87,7 +84,7 @@ public class OlmSessionTest {
aliceAccount = new OlmAccount(); aliceAccount = new OlmAccount();
bobAccount = new OlmAccount(); bobAccount = new OlmAccount();
} catch (OlmException e) { } catch (OlmException e) {
fail(e.getMessage()); assertTrue(e.getMessage(),false);
} }
// test accounts creation // test accounts creation
@ -100,17 +97,17 @@ public class OlmSessionTest {
try { try {
bobIdentityKeys = bobAccount.identityKeys(); bobIdentityKeys = bobAccount.identityKeys();
} catch (Exception e) { } catch (Exception e) {
fail("identityKeys failed " + e.getMessage()); assertTrue("identityKeys failed " + e.getMessage(), false);
} }
bobIdentityKey = TestHelper.getIdentityKey(bobIdentityKeys); bobIdentityKey = TestHelper.getIdentityKey(bobIdentityKeys);
assertNotNull(bobIdentityKey); assertTrue(null!=bobIdentityKey);
// get bob one time keys // get bob one time keys
try { try {
bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER); bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
Map<String, Map<String, String>> bobOneTimeKeys = null; Map<String, Map<String, String>> bobOneTimeKeys = null;
@ -118,7 +115,7 @@ public class OlmSessionTest {
try { try {
bobOneTimeKeys = bobAccount.oneTimeKeys(); bobOneTimeKeys = bobAccount.oneTimeKeys();
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
bobOneTimeKey = TestHelper.getOneTimeKey(bobOneTimeKeys,1); bobOneTimeKey = TestHelper.getOneTimeKey(bobOneTimeKeys,1);
@ -129,7 +126,7 @@ public class OlmSessionTest {
try { try {
aliceSession = new OlmSession(); aliceSession = new OlmSession();
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception Msg=" + e.getMessage()); assertTrue("Exception Msg="+e.getMessage(), false);
} }
assertTrue(0!=aliceSession.getOlmSessionId()); assertTrue(0!=aliceSession.getOlmSessionId());
@ -137,14 +134,14 @@ public class OlmSessionTest {
try { try {
aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey); aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
String clearMsg = "Heloo bob , this is alice!"; String clearMsg = "Heloo bob , this is alice!";
OlmMessage encryptedMsgToBob = null; OlmMessage encryptedMsgToBob = null;
try { try {
encryptedMsgToBob = aliceSession.encryptMessage(clearMsg); encryptedMsgToBob = aliceSession.encryptMessage(clearMsg);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(encryptedMsgToBob); assertNotNull(encryptedMsgToBob);
assertNotNull(encryptedMsgToBob.mCipherText); assertNotNull(encryptedMsgToBob.mCipherText);
@ -155,32 +152,32 @@ public class OlmSessionTest {
try { try {
bobSession = new OlmSession(); bobSession = new OlmSession();
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception Msg=" + e.getMessage()); assertTrue("Exception Msg="+e.getMessage(), false);
} }
assertTrue(0!=bobSession.getOlmSessionId()); assertTrue(0!=bobSession.getOlmSessionId());
try { try {
bobSession.initInboundSession(bobAccount, encryptedMsgToBob.mCipherText); bobSession.initInboundSession(bobAccount, encryptedMsgToBob.mCipherText);
} catch (Exception e) { } catch (Exception e) {
fail("initInboundSessionWithAccount failed " + e.getMessage()); assertTrue("initInboundSessionWithAccount failed " + e.getMessage(), false);
} }
String decryptedMsg = null; String decryptedMsg = null;
try { try {
decryptedMsg = bobSession.decryptMessage(encryptedMsgToBob); decryptedMsg = bobSession.decryptMessage(encryptedMsgToBob);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(decryptedMsg); assertNotNull(decryptedMsg);
// MESSAGE COMPARISON: decrypted vs encrypted // MESSAGE COMPARISON: decrypted vs encrypted
assertEquals(clearMsg, decryptedMsg); assertTrue(clearMsg.equals(decryptedMsg));
// clean objects.. // clean objects..
try { try {
bobAccount.removeOneTimeKeys(bobSession); bobAccount.removeOneTimeKeys(bobSession);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
// release accounts // release accounts
@ -223,7 +220,7 @@ public class OlmSessionTest {
aliceAccount = new OlmAccount(); aliceAccount = new OlmAccount();
bobAccount = new OlmAccount(); bobAccount = new OlmAccount();
} catch (OlmException e) { } catch (OlmException e) {
fail(e.getMessage()); assertTrue(e.getMessage(),false);
} }
// test accounts creation // test accounts creation
@ -236,17 +233,17 @@ public class OlmSessionTest {
try { try {
bobIdentityKeys = bobAccount.identityKeys(); bobIdentityKeys = bobAccount.identityKeys();
} catch (Exception e) { } catch (Exception e) {
fail("identityKeys failed " + e.getMessage()); assertTrue("identityKeys failed " + e.getMessage(), false);
} }
bobIdentityKey = TestHelper.getIdentityKey(bobIdentityKeys); bobIdentityKey = TestHelper.getIdentityKey(bobIdentityKeys);
assertNotNull(bobIdentityKey); assertTrue(null!=bobIdentityKey);
// get bob one time keys // get bob one time keys
try { try {
bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER); bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
Map<String, Map<String, String>> bobOneTimeKeys = null; Map<String, Map<String, String>> bobOneTimeKeys = null;
@ -254,7 +251,7 @@ public class OlmSessionTest {
try { try {
bobOneTimeKeys = bobAccount.oneTimeKeys(); bobOneTimeKeys = bobAccount.oneTimeKeys();
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
bobOneTimeKey = TestHelper.getOneTimeKey(bobOneTimeKeys,1); bobOneTimeKey = TestHelper.getOneTimeKey(bobOneTimeKeys,1);
@ -265,7 +262,7 @@ public class OlmSessionTest {
try { try {
aliceSession = new OlmSession(); aliceSession = new OlmSession();
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception Msg=" + e.getMessage()); assertTrue("Exception Msg="+e.getMessage(), false);
} }
assertTrue(0!=aliceSession.getOlmSessionId()); assertTrue(0!=aliceSession.getOlmSessionId());
@ -273,7 +270,7 @@ public class OlmSessionTest {
try { try {
aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey); aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
String helloClearMsg = "Hello I'm Alice!"; String helloClearMsg = "Hello I'm Alice!";
@ -283,7 +280,7 @@ public class OlmSessionTest {
try { try {
encryptedAliceToBobMsg1 = aliceSession.encryptMessage(helloClearMsg); encryptedAliceToBobMsg1 = aliceSession.encryptMessage(helloClearMsg);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(encryptedAliceToBobMsg1); assertNotNull(encryptedAliceToBobMsg1);
@ -294,7 +291,7 @@ public class OlmSessionTest {
try { try {
bobSession = new OlmSession(); bobSession = new OlmSession();
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception Msg=" + e.getMessage()); assertTrue("Exception Msg="+e.getMessage(), false);
} }
assertTrue(0!=bobSession.getOlmSessionId()); assertTrue(0!=bobSession.getOlmSessionId());
@ -302,7 +299,7 @@ public class OlmSessionTest {
try { try {
bobSession.initInboundSession(bobAccount, encryptedAliceToBobMsg1.mCipherText); bobSession.initInboundSession(bobAccount, encryptedAliceToBobMsg1.mCipherText);
} catch (Exception e) { } catch (Exception e) {
fail("initInboundSessionWithAccount failed " + e.getMessage()); assertTrue("initInboundSessionWithAccount failed " + e.getMessage(), false);
} }
// DECRYPT MESSAGE FROM ALICE // DECRYPT MESSAGE FROM ALICE
@ -310,12 +307,12 @@ public class OlmSessionTest {
try { try {
decryptedMsg01 = bobSession.decryptMessage(encryptedAliceToBobMsg1); decryptedMsg01 = bobSession.decryptMessage(encryptedAliceToBobMsg1);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(decryptedMsg01); assertNotNull(decryptedMsg01);
// MESSAGE COMPARISON: decrypted vs encrypted // MESSAGE COMPARISON: decrypted vs encrypted
assertEquals(helloClearMsg, decryptedMsg01); assertTrue(helloClearMsg.equals(decryptedMsg01));
// BACK/FORTH MESSAGE COMPARISON // BACK/FORTH MESSAGE COMPARISON
String clearMsg1 = "Hello I'm Bob!"; String clearMsg1 = "Hello I'm Bob!";
@ -327,7 +324,7 @@ public class OlmSessionTest {
try { try {
encryptedMsg1 = bobSession.encryptMessage(clearMsg1); encryptedMsg1 = bobSession.encryptMessage(clearMsg1);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(encryptedMsg1); assertNotNull(encryptedMsg1);
@ -335,7 +332,7 @@ public class OlmSessionTest {
try { try {
encryptedMsg2 = bobSession.encryptMessage(clearMsg2); encryptedMsg2 = bobSession.encryptMessage(clearMsg2);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(encryptedMsg2); assertNotNull(encryptedMsg2);
@ -344,7 +341,7 @@ public class OlmSessionTest {
try { try {
encryptedMsg3 = bobSession.encryptMessage(clearMsg3); encryptedMsg3 = bobSession.encryptMessage(clearMsg3);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(encryptedMsg3); assertNotNull(encryptedMsg3);
@ -353,7 +350,7 @@ public class OlmSessionTest {
try { try {
decryptedMsg1 = aliceSession.decryptMessage(encryptedMsg1); decryptedMsg1 = aliceSession.decryptMessage(encryptedMsg1);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(decryptedMsg1); assertNotNull(decryptedMsg1);
@ -361,7 +358,7 @@ public class OlmSessionTest {
try { try {
decryptedMsg2 = aliceSession.decryptMessage(encryptedMsg2); decryptedMsg2 = aliceSession.decryptMessage(encryptedMsg2);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(decryptedMsg2); assertNotNull(decryptedMsg2);
@ -369,14 +366,14 @@ public class OlmSessionTest {
try { try {
decryptedMsg3 = aliceSession.decryptMessage(encryptedMsg3); decryptedMsg3 = aliceSession.decryptMessage(encryptedMsg3);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(decryptedMsg3); assertNotNull(decryptedMsg3);
// comparison tests // comparison tests
assertEquals(clearMsg1, decryptedMsg1); assertTrue(clearMsg1.equals(decryptedMsg1));
assertEquals(clearMsg2, decryptedMsg2); assertTrue(clearMsg2.equals(decryptedMsg2));
assertEquals(clearMsg3, decryptedMsg3); assertTrue(clearMsg3.equals(decryptedMsg3));
// and one more from alice to bob // and one more from alice to bob
clearMsg1 = "another message from Alice to Bob!!"; clearMsg1 = "another message from Alice to Bob!!";
@ -385,7 +382,7 @@ public class OlmSessionTest {
try { try {
encryptedMsg1 = aliceSession.encryptMessage(clearMsg1); encryptedMsg1 = aliceSession.encryptMessage(clearMsg1);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(encryptedMsg1); assertNotNull(encryptedMsg1);
@ -393,20 +390,20 @@ public class OlmSessionTest {
try { try {
decryptedMsg1 = bobSession.decryptMessage(encryptedMsg1); decryptedMsg1 = bobSession.decryptMessage(encryptedMsg1);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(decryptedMsg1); assertNotNull(decryptedMsg1);
assertEquals(clearMsg1, decryptedMsg1); assertTrue(clearMsg1.equals(decryptedMsg1));
// comparison test // comparison test
assertEquals(clearMsg1, decryptedMsg1); assertTrue(clearMsg1.equals(decryptedMsg1));
// clean objects.. // clean objects..
try { try {
bobAccount.removeOneTimeKeys(bobSession); bobAccount.removeOneTimeKeys(bobSession);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
bobAccount.releaseAccount(); bobAccount.releaseAccount();
@ -430,7 +427,7 @@ public class OlmSessionTest {
aliceAccount = new OlmAccount(); aliceAccount = new OlmAccount();
bobAccount = new OlmAccount(); bobAccount = new OlmAccount();
} catch (OlmException e) { } catch (OlmException e) {
fail(e.getMessage()); assertTrue(e.getMessage(),false);
} }
// test accounts creation // test accounts creation
@ -443,7 +440,7 @@ public class OlmSessionTest {
try { try {
aliceSession = new OlmSession(); aliceSession = new OlmSession();
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception Msg=" + e.getMessage()); assertTrue("Exception Msg="+e.getMessage(), false);
} }
assertTrue(0!=aliceSession.getOlmSessionId()); assertTrue(0!=aliceSession.getOlmSessionId());
@ -453,7 +450,7 @@ public class OlmSessionTest {
bobSession = new OlmSession(); bobSession = new OlmSession();
} catch (OlmException e) { } catch (OlmException e) {
e.printStackTrace(); e.printStackTrace();
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertTrue(0!=bobSession.getOlmSessionId()); assertTrue(0!=bobSession.getOlmSessionId());
@ -461,7 +458,7 @@ public class OlmSessionTest {
try { try {
aliceSessionId = aliceSession.sessionIdentifier(); aliceSessionId = aliceSession.sessionIdentifier();
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(aliceSessionId); assertNotNull(aliceSessionId);
@ -470,12 +467,12 @@ public class OlmSessionTest {
try { try {
bobSessionId = bobSession.sessionIdentifier(); bobSessionId = bobSession.sessionIdentifier();
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(bobSessionId); assertNotNull(bobSessionId);
// must be the same for both ends of the conversation // must be the same for both ends of the conversation
assertEquals(aliceSessionId, bobSessionId); assertTrue(aliceSessionId.equals(bobSessionId));
aliceAccount.releaseAccount(); aliceAccount.releaseAccount();
bobAccount.releaseAccount(); bobAccount.releaseAccount();
@ -498,7 +495,7 @@ public class OlmSessionTest {
aliceAccount = new OlmAccount(); aliceAccount = new OlmAccount();
bobAccount = new OlmAccount(); bobAccount = new OlmAccount();
} catch (OlmException e) { } catch (OlmException e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
// CREATE ALICE SESSION // CREATE ALICE SESSION
@ -506,7 +503,7 @@ public class OlmSessionTest {
aliceSession = new OlmSession(); aliceSession = new OlmSession();
bobSession = new OlmSession(); bobSession = new OlmSession();
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception Msg=" + e.getMessage()); assertTrue("Exception Msg=" + e.getMessage(), false);
} }
// get bob/luke identity key // get bob/luke identity key
@ -515,7 +512,7 @@ public class OlmSessionTest {
try { try {
bobIdentityKeys = bobAccount.identityKeys(); bobIdentityKeys = bobAccount.identityKeys();
} catch (Exception e) { } catch (Exception e) {
fail("identityKeys failed " + e.getMessage()); assertTrue("identityKeys failed " + e.getMessage(), false);
} }
Map<String, String> aliceIdentityKeys = null; Map<String, String> aliceIdentityKeys = null;
@ -523,7 +520,7 @@ public class OlmSessionTest {
try { try {
aliceIdentityKeys = aliceAccount.identityKeys(); aliceIdentityKeys = aliceAccount.identityKeys();
} catch (Exception e) { } catch (Exception e) {
fail("identityKeys failed " + e.getMessage()); assertTrue("identityKeys failed " + e.getMessage(), false);
} }
String bobIdentityKey = TestHelper.getIdentityKey(bobIdentityKeys); String bobIdentityKey = TestHelper.getIdentityKey(bobIdentityKeys);
@ -533,13 +530,13 @@ public class OlmSessionTest {
try { try {
bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER); bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
try { try {
aliceAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER); aliceAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
Map<String, Map<String, String>> bobOneTimeKeys = null; Map<String, Map<String, String>> bobOneTimeKeys = null;
@ -547,7 +544,7 @@ public class OlmSessionTest {
try { try {
bobOneTimeKeys = bobAccount.oneTimeKeys(); bobOneTimeKeys = bobAccount.oneTimeKeys();
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
String bobOneTimeKey1 = TestHelper.getOneTimeKey(bobOneTimeKeys, 1); String bobOneTimeKey1 = TestHelper.getOneTimeKey(bobOneTimeKeys, 1);
@ -556,7 +553,7 @@ public class OlmSessionTest {
try { try {
aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey1); aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey1);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
String aliceClearMsg = "hello helooo to bob!"; String aliceClearMsg = "hello helooo to bob!";
@ -565,7 +562,7 @@ public class OlmSessionTest {
try { try {
encryptedAliceToBobMsg1 = aliceSession.encryptMessage(aliceClearMsg); encryptedAliceToBobMsg1 = aliceSession.encryptMessage(aliceClearMsg);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertFalse(bobSession.matchesInboundSession(encryptedAliceToBobMsg1.mCipherText)); assertFalse(bobSession.matchesInboundSession(encryptedAliceToBobMsg1.mCipherText));
@ -574,7 +571,7 @@ public class OlmSessionTest {
try { try {
bobSession.initInboundSession(bobAccount, encryptedAliceToBobMsg1.mCipherText); bobSession.initInboundSession(bobAccount, encryptedAliceToBobMsg1.mCipherText);
} catch (Exception e) { } catch (Exception e) {
fail("initInboundSessionWithAccount failed " + e.getMessage()); assertTrue("initInboundSessionWithAccount failed " + e.getMessage(), false);
} }
// test matchesInboundSession() and matchesInboundSessionFrom() // test matchesInboundSession() and matchesInboundSessionFrom()
@ -587,7 +584,7 @@ public class OlmSessionTest {
try { try {
bobAccount.removeOneTimeKeys(bobSession); bobAccount.removeOneTimeKeys(bobSession);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
aliceAccount.releaseAccount(); aliceAccount.releaseAccount();
@ -604,7 +601,6 @@ public class OlmSessionTest {
// ******************************************************** // ********************************************************
// ************* SERIALIZATION TEST *********************** // ************* SERIALIZATION TEST ***********************
// ******************************************************** // ********************************************************
/** /**
* Same as {@link #test02AliceToBobBackAndForth()}, but alice's session * Same as {@link #test02AliceToBobBackAndForth()}, but alice's session
* is serialized and de-serialized before performing the final * is serialized and de-serialized before performing the final
@ -624,7 +620,7 @@ public class OlmSessionTest {
aliceAccount = new OlmAccount(); aliceAccount = new OlmAccount();
bobAccount = new OlmAccount(); bobAccount = new OlmAccount();
} catch (OlmException e) { } catch (OlmException e) {
fail(e.getMessage()); assertTrue(e.getMessage(),false);
} }
// test accounts creation // test accounts creation
@ -637,17 +633,17 @@ public class OlmSessionTest {
try { try {
bobIdentityKeys = bobAccount.identityKeys(); bobIdentityKeys = bobAccount.identityKeys();
} catch (Exception e) { } catch (Exception e) {
fail("identityKeys failed " + e.getMessage()); assertTrue("identityKeys failed " + e.getMessage(), false);
} }
bobIdentityKey = TestHelper.getIdentityKey(bobIdentityKeys); bobIdentityKey = TestHelper.getIdentityKey(bobIdentityKeys);
assertNotNull(bobIdentityKey); assertTrue(null!=bobIdentityKey);
// get bob one time keys // get bob one time keys
try { try {
bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER); bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
Map<String, Map<String, String>> bobOneTimeKeys = null; Map<String, Map<String, String>> bobOneTimeKeys = null;
@ -655,7 +651,7 @@ public class OlmSessionTest {
try { try {
bobOneTimeKeys = bobAccount.oneTimeKeys(); bobOneTimeKeys = bobAccount.oneTimeKeys();
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
bobOneTimeKey = TestHelper.getOneTimeKey(bobOneTimeKeys,1); bobOneTimeKey = TestHelper.getOneTimeKey(bobOneTimeKeys,1);
@ -666,7 +662,7 @@ public class OlmSessionTest {
try { try {
aliceSession = new OlmSession(); aliceSession = new OlmSession();
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception Msg=" + e.getMessage()); assertTrue("Exception Msg="+e.getMessage(), false);
} }
assertTrue(0!=aliceSession.getOlmSessionId()); assertTrue(0!=aliceSession.getOlmSessionId());
@ -674,7 +670,7 @@ public class OlmSessionTest {
try { try {
aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey); aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
String helloClearMsg = "Hello I'm Alice!"; String helloClearMsg = "Hello I'm Alice!";
@ -683,7 +679,7 @@ public class OlmSessionTest {
try { try {
encryptedAliceToBobMsg1 = aliceSession.encryptMessage(helloClearMsg); encryptedAliceToBobMsg1 = aliceSession.encryptMessage(helloClearMsg);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(encryptedAliceToBobMsg1); assertNotNull(encryptedAliceToBobMsg1);
assertNotNull(encryptedAliceToBobMsg1.mCipherText); assertNotNull(encryptedAliceToBobMsg1.mCipherText);
@ -693,7 +689,7 @@ public class OlmSessionTest {
try { try {
bobSession = new OlmSession(); bobSession = new OlmSession();
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception Msg=" + e.getMessage()); assertTrue("Exception Msg="+e.getMessage(), false);
} }
assertTrue(0!=bobSession.getOlmSessionId()); assertTrue(0!=bobSession.getOlmSessionId());
@ -701,7 +697,7 @@ public class OlmSessionTest {
try { try {
bobSession.initInboundSession(bobAccount, encryptedAliceToBobMsg1.mCipherText); bobSession.initInboundSession(bobAccount, encryptedAliceToBobMsg1.mCipherText);
} catch (Exception e) { } catch (Exception e) {
fail("initInboundSessionWithAccount failed " + e.getMessage()); assertTrue("initInboundSessionWithAccount failed " + e.getMessage(), false);
} }
// DECRYPT MESSAGE FROM ALICE // DECRYPT MESSAGE FROM ALICE
@ -710,13 +706,13 @@ public class OlmSessionTest {
try { try {
decryptedMsg01 = bobSession.decryptMessage(encryptedAliceToBobMsg1); decryptedMsg01 = bobSession.decryptMessage(encryptedAliceToBobMsg1);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(decryptedMsg01); assertNotNull(decryptedMsg01);
// MESSAGE COMPARISON: decrypted vs encrypted // MESSAGE COMPARISON: decrypted vs encrypted
assertEquals(helloClearMsg, decryptedMsg01); assertTrue(helloClearMsg.equals(decryptedMsg01));
// BACK/FORTH MESSAGE COMPARISON // BACK/FORTH MESSAGE COMPARISON
String clearMsg1 = "Hello I'm Bob!"; String clearMsg1 = "Hello I'm Bob!";
@ -728,7 +724,7 @@ public class OlmSessionTest {
try { try {
encryptedMsg1 = bobSession.encryptMessage(clearMsg1); encryptedMsg1 = bobSession.encryptMessage(clearMsg1);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(encryptedMsg1); assertNotNull(encryptedMsg1);
@ -736,7 +732,7 @@ public class OlmSessionTest {
try { try {
encryptedMsg2 = bobSession.encryptMessage(clearMsg2); encryptedMsg2 = bobSession.encryptMessage(clearMsg2);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(encryptedMsg2); assertNotNull(encryptedMsg2);
@ -744,12 +740,12 @@ public class OlmSessionTest {
try { try {
encryptedMsg3 = bobSession.encryptMessage(clearMsg3); encryptedMsg3 = bobSession.encryptMessage(clearMsg3);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(encryptedMsg3); assertNotNull(encryptedMsg3);
// serialize alice session // serialize alice session
Context context = ApplicationProvider.getApplicationContext(); Context context = getInstrumentation().getContext();
try { try {
FileOutputStream fileOutput = context.openFileOutput(FILE_NAME_SERIAL_SESSION, Context.MODE_PRIVATE); FileOutputStream fileOutput = context.openFileOutput(FILE_NAME_SERIAL_SESSION, Context.MODE_PRIVATE);
ObjectOutputStream objectOutput = new ObjectOutputStream(fileOutput); ObjectOutputStream objectOutput = new ObjectOutputStream(fileOutput);
@ -775,15 +771,15 @@ public class OlmSessionTest {
assertNotNull(decryptedMsg3); assertNotNull(decryptedMsg3);
// comparison tests // comparison tests
assertEquals(clearMsg1, decryptedMsg1); assertTrue(clearMsg1.equals(decryptedMsg1));
assertEquals(clearMsg2, decryptedMsg2); assertTrue(clearMsg2.equals(decryptedMsg2));
assertEquals(clearMsg3, decryptedMsg3); assertTrue(clearMsg3.equals(decryptedMsg3));
// clean objects.. // clean objects..
try { try {
bobAccount.removeOneTimeKeys(bobSession); bobAccount.removeOneTimeKeys(bobSession);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
bobAccount.releaseAccount(); bobAccount.releaseAccount();
@ -797,21 +793,25 @@ public class OlmSessionTest {
assertTrue(bobSession.isReleased()); assertTrue(bobSession.isReleased());
assertTrue(aliceSession.isReleased()); assertTrue(aliceSession.isReleased());
assertTrue(aliceSessionDeserial.isReleased()); assertTrue(aliceSessionDeserial.isReleased());
} catch (FileNotFoundException e) { }
catch (FileNotFoundException e) {
Log.e(LOG_TAG, "## test03SessionSerialization(): Exception FileNotFoundException Msg=="+e.getMessage()); Log.e(LOG_TAG, "## test03SessionSerialization(): Exception FileNotFoundException Msg=="+e.getMessage());
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} catch (ClassNotFoundException e) { }
catch (ClassNotFoundException e) {
Log.e(LOG_TAG, "## test03SessionSerialization(): Exception ClassNotFoundException Msg==" + e.getMessage()); Log.e(LOG_TAG, "## test03SessionSerialization(): Exception ClassNotFoundException Msg==" + e.getMessage());
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} catch (IOException e) { }
catch (IOException e) {
Log.e(LOG_TAG, "## test03SessionSerialization(): Exception IOException Msg==" + e.getMessage()); Log.e(LOG_TAG, "## test03SessionSerialization(): Exception IOException Msg==" + e.getMessage());
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
/*catch (OlmException e) { /*catch (OlmException e) {
Log.e(LOG_TAG, "## test03SessionSerialization(): Exception OlmException Msg==" + e.getMessage()); Log.e(LOG_TAG, "## test03SessionSerialization(): Exception OlmException Msg==" + e.getMessage());
}*/ catch (Exception e) { }*/
catch (Exception e) {
Log.e(LOG_TAG, "## test03SessionSerialization(): Exception Msg==" + e.getMessage()); Log.e(LOG_TAG, "## test03SessionSerialization(): Exception Msg==" + e.getMessage());
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
} }
@ -831,7 +831,7 @@ public class OlmSessionTest {
aliceAccount = new OlmAccount(); aliceAccount = new OlmAccount();
bobAccount = new OlmAccount(); bobAccount = new OlmAccount();
} catch (OlmException e) { } catch (OlmException e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
// get bob identity key // get bob identity key
@ -840,17 +840,17 @@ public class OlmSessionTest {
try { try {
bobIdentityKeys = bobAccount.identityKeys(); bobIdentityKeys = bobAccount.identityKeys();
} catch (Exception e) { } catch (Exception e) {
fail("identityKeys failed " + e.getMessage()); assertTrue("identityKeys failed " + e.getMessage(), false);
} }
String bobIdentityKey = TestHelper.getIdentityKey(bobIdentityKeys); String bobIdentityKey = TestHelper.getIdentityKey(bobIdentityKeys);
assertNotNull(bobIdentityKey); assertTrue(null != bobIdentityKey);
// get bob one time keys // get bob one time keys
try { try {
bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER); bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
Map<String, Map<String, String>> bobOneTimeKeys = null; Map<String, Map<String, String>> bobOneTimeKeys = null;
@ -858,7 +858,7 @@ public class OlmSessionTest {
try { try {
bobOneTimeKeys = bobAccount.oneTimeKeys(); bobOneTimeKeys = bobAccount.oneTimeKeys();
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(bobOneTimeKeys); assertNotNull(bobOneTimeKeys);
@ -870,7 +870,7 @@ public class OlmSessionTest {
try { try {
aliceSession = new OlmSession(); aliceSession = new OlmSession();
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception Msg=" + e.getMessage()); assertTrue("Exception Msg=" + e.getMessage(), false);
} }
// SANITY CHECK TESTS FOR: initOutboundSessionWithAccount() // SANITY CHECK TESTS FOR: initOutboundSessionWithAccount()
@ -880,7 +880,7 @@ public class OlmSessionTest {
} catch (Exception e) { } catch (Exception e) {
errorMessage = e.getMessage(); errorMessage = e.getMessage();
} }
assertNotNull(errorMessage); assertTrue(null != errorMessage);
errorMessage = null; errorMessage = null;
try { try {
@ -888,7 +888,7 @@ public class OlmSessionTest {
} catch (Exception e) { } catch (Exception e) {
errorMessage = e.getMessage(); errorMessage = e.getMessage();
} }
assertNotNull(errorMessage); assertTrue(null != errorMessage);
errorMessage = null; errorMessage = null;
try { try {
@ -896,7 +896,7 @@ public class OlmSessionTest {
} catch (Exception e) { } catch (Exception e) {
errorMessage = e.getMessage(); errorMessage = e.getMessage();
} }
assertNotNull(errorMessage); assertTrue(null != errorMessage);
errorMessage = null; errorMessage = null;
try { try {
@ -904,7 +904,7 @@ public class OlmSessionTest {
} catch (Exception e) { } catch (Exception e) {
errorMessage = e.getMessage(); errorMessage = e.getMessage();
} }
assertNotNull(errorMessage); assertTrue(null != errorMessage);
// init properly // init properly
errorMessage = null; errorMessage = null;
@ -913,23 +913,23 @@ public class OlmSessionTest {
} catch (Exception e) { } catch (Exception e) {
errorMessage = e.getMessage(); errorMessage = e.getMessage();
} }
assertNull(errorMessage); assertTrue(null == errorMessage);
// SANITY CHECK TESTS FOR: encryptMessage() // SANITY CHECK TESTS FOR: encryptMessage()
OlmMessage message = null; OlmMessage message = null;
try { try {
message = aliceSession.encryptMessage(null); message = aliceSession.encryptMessage(null);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNull(message); assertTrue(null==message);
// encrypt properly // encrypt properly
OlmMessage encryptedMsgToBob = null; OlmMessage encryptedMsgToBob = null;
try { try {
encryptedMsgToBob = aliceSession.encryptMessage("A message for bob"); encryptedMsgToBob = aliceSession.encryptMessage("A message for bob");
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(encryptedMsgToBob); assertNotNull(encryptedMsgToBob);
@ -944,7 +944,7 @@ public class OlmSessionTest {
errorMessage = e.getMessage(); errorMessage = e.getMessage();
} }
assertFalse(TextUtils.isEmpty(errorMessage)); assertTrue(!TextUtils.isEmpty(errorMessage));
errorMessage = null; errorMessage = null;
try { try {
@ -953,7 +953,7 @@ public class OlmSessionTest {
errorMessage = e.getMessage(); errorMessage = e.getMessage();
} }
assertFalse(TextUtils.isEmpty(errorMessage)); assertTrue(!TextUtils.isEmpty(errorMessage));
errorMessage = null; errorMessage = null;
try { try {
@ -962,7 +962,7 @@ public class OlmSessionTest {
errorMessage = e.getMessage(); errorMessage = e.getMessage();
} }
assertFalse(TextUtils.isEmpty(errorMessage)); assertTrue(!TextUtils.isEmpty(errorMessage));
// init properly // init properly
errorMessage = null; errorMessage = null;
@ -974,7 +974,7 @@ public class OlmSessionTest {
assertTrue(TextUtils.isEmpty(errorMessage)); assertTrue(TextUtils.isEmpty(errorMessage));
} catch (OlmException e) { } catch (OlmException e) {
fail("Exception Msg=" + e.getMessage()); assertTrue("Exception Msg="+e.getMessage(), false);
} }
// SANITY CHECK TESTS FOR: decryptMessage() // SANITY CHECK TESTS FOR: decryptMessage()
@ -982,22 +982,22 @@ public class OlmSessionTest {
try { try {
decryptedMsg = aliceSession.decryptMessage(null); decryptedMsg = aliceSession.decryptMessage(null);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNull(decryptedMsg); assertTrue(null==decryptedMsg);
// SANITY CHECK TESTS FOR: matchesInboundSession() // SANITY CHECK TESTS FOR: matchesInboundSession()
assertFalse(aliceSession.matchesInboundSession(null)); assertTrue(!aliceSession.matchesInboundSession(null));
// SANITY CHECK TESTS FOR: matchesInboundSessionFrom() // SANITY CHECK TESTS FOR: matchesInboundSessionFrom()
assertFalse(aliceSession.matchesInboundSessionFrom(null, null)); assertTrue(!aliceSession.matchesInboundSessionFrom(null,null));
// release objects // release objects
try { try {
bobAccount.removeOneTimeKeys(bobSession); bobAccount.removeOneTimeKeys(bobSession);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
aliceAccount.releaseAccount(); aliceAccount.releaseAccount();
@ -1011,75 +1011,4 @@ public class OlmSessionTest {
assertTrue(bobSession.isReleased()); assertTrue(bobSession.isReleased());
} }
@Test
public void test07AliceBobSessionDescribe() {
// creates alice & bob accounts
OlmAccount aliceAccount = null;
OlmAccount bobAccount = null;
try {
aliceAccount = new OlmAccount();
bobAccount = new OlmAccount();
} catch (OlmException e) {
fail(e.getMessage());
}
// test accounts creation
assertTrue(0 != bobAccount.getOlmAccountId());
assertTrue(0 != aliceAccount.getOlmAccountId());
// CREATE ALICE SESSION
OlmSession aliceSession = null;
try {
aliceSession = new OlmSession();
} catch (OlmException e) {
fail("Exception Msg=" + e.getMessage());
}
assertTrue(0 != aliceSession.getOlmSessionId());
// CREATE ALICE SESSION
OlmSession bobSession = null;
try {
bobSession = new OlmSession();
} catch (OlmException e) {
e.printStackTrace();
fail(e.getMessage());
}
assertTrue(0 != bobSession.getOlmSessionId());
String aliceSessionDescribe = null;
try {
aliceSessionDescribe = aliceSession.sessionDescribe();
} catch (Exception e) {
fail(e.getMessage());
}
assertNotNull(aliceSessionDescribe);
String bobSessionDescribe = null;
try {
bobSessionDescribe = bobSession.sessionDescribe();
} catch (Exception e) {
fail(e.getMessage());
}
assertNotNull(bobSessionDescribe);
// must be the same for both ends of the conversation
assertEquals(aliceSessionDescribe, bobSessionDescribe);
assertEquals(
"sender chain index: 0 receiver chain indices: skipped message keys:",
aliceSessionDescribe
);
aliceAccount.releaseAccount();
bobAccount.releaseAccount();
assertTrue(aliceAccount.isReleased());
assertTrue(bobAccount.isReleased());
bobSession.releaseSession();
aliceSession.releaseSession();
assertTrue(bobSession.isReleased());
assertTrue(aliceSession.isReleased());
}
} }

View file

@ -17,11 +17,11 @@
package org.matrix.olm; package org.matrix.olm;
import android.support.test.runner.AndroidJUnit4;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import androidx.test.ext.junit.runners.AndroidJUnit4; import org.json.JSONObject;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.FixMethodOrder; import org.junit.FixMethodOrder;
import org.junit.Test; import org.junit.Test;
@ -33,7 +33,6 @@ import java.util.Map;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING) @FixMethodOrder(MethodSorters.NAME_ASCENDING)
@ -67,7 +66,7 @@ public class OlmUtilityTest {
try { try {
account = new OlmAccount(); account = new OlmAccount();
} catch (OlmException e) { } catch (OlmException e) {
fail(e.getMessage()); assertTrue(e.getMessage(),false);
} }
assertNotNull(account); assertNotNull(account);
@ -77,7 +76,7 @@ public class OlmUtilityTest {
try { try {
messageSignature = account.signMessage(message); messageSignature = account.signMessage(message);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); assertTrue(e.getMessage(), false);
} }
assertNotNull(messageSignature); assertNotNull(messageSignature);
@ -88,12 +87,12 @@ public class OlmUtilityTest {
try { try {
identityKeys = account.identityKeys(); identityKeys = account.identityKeys();
} catch (Exception e) { } catch (Exception e) {
fail("identityKeys failed " + e.getMessage()); assertTrue("identityKeys failed " + e.getMessage(), false);
} }
assertNotNull(identityKeys); assertNotNull(identityKeys);
fingerPrintKey = TestHelper.getFingerprintKey(identityKeys); fingerPrintKey = TestHelper.getFingerprintKey(identityKeys);
assertFalse("fingerprint key missing", TextUtils.isEmpty(fingerPrintKey)); assertTrue("fingerprint key missing",!TextUtils.isEmpty(fingerPrintKey));
// instantiate utility object // instantiate utility object
OlmUtility utility = null; OlmUtility utility = null;
@ -101,7 +100,7 @@ public class OlmUtilityTest {
try { try {
utility = new OlmUtility(); utility = new OlmUtility();
} catch (Exception e) { } catch (Exception e) {
fail("failed to create OlmUtility"); assertTrue("failed to create OlmUtility", false);
} }
// verify signature // verify signature
@ -122,7 +121,7 @@ public class OlmUtilityTest {
} catch (Exception e) { } catch (Exception e) {
errorMsg = e.getMessage(); errorMsg = e.getMessage();
} }
assertFalse(TextUtils.isEmpty(errorMsg)); assertTrue(!TextUtils.isEmpty(errorMsg));
// check bad fingerprint size => errorMsg = INVALID_BASE64 // check bad fingerprint size => errorMsg = INVALID_BASE64
String badSizeFingerPrintKey = fingerPrintKey.substring(fingerPrintKey.length()/2); String badSizeFingerPrintKey = fingerPrintKey.substring(fingerPrintKey.length()/2);
@ -133,7 +132,7 @@ public class OlmUtilityTest {
} catch (Exception e) { } catch (Exception e) {
errorMsg = e.getMessage(); errorMsg = e.getMessage();
} }
assertFalse(TextUtils.isEmpty(errorMsg)); assertTrue(!TextUtils.isEmpty(errorMsg));
utility.releaseUtility(); utility.releaseUtility();
assertTrue(utility.isReleased()); assertTrue(utility.isReleased());
@ -149,7 +148,7 @@ public class OlmUtilityTest {
try { try {
utility = new OlmUtility(); utility = new OlmUtility();
} catch (Exception e) { } catch (Exception e) {
fail("OlmUtility creation failed"); assertTrue("OlmUtility creation failed", false);
} }
String msgToHash = "The quick brown fox jumps over the lazy dog"; String msgToHash = "The quick brown fox jumps over the lazy dog";

View file

@ -22,7 +22,6 @@ import java.util.Map;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/** /**
* Helper class providing helper methods used in the Olm Android SDK unit tests. * Helper class providing helper methods used in the Olm Android SDK unit tests.
@ -40,7 +39,7 @@ public class TestHelper {
try { try {
idKey = aIdentityKeysMap.get(OlmAccount.JSON_KEY_IDENTITY_KEY); idKey = aIdentityKeysMap.get(OlmAccount.JSON_KEY_IDENTITY_KEY);
} catch (Exception e) { } catch (Exception e) {
fail("Exception MSg=" + e.getMessage()); assertTrue("Exception MSg=" + e.getMessage(), false);
} }
return idKey; return idKey;
} }
@ -56,7 +55,7 @@ public class TestHelper {
try { try {
fingerprintKey = aIdentityKeysMap.get(OlmAccount.JSON_KEY_FINGER_PRINT_KEY); fingerprintKey = aIdentityKeysMap.get(OlmAccount.JSON_KEY_FINGER_PRINT_KEY);
} catch (Exception e) { } catch (Exception e) {
fail("Exception MSg=" + e.getMessage()); assertTrue("Exception MSg=" + e.getMessage(), false);
} }
return fingerprintKey; return fingerprintKey;
} }
@ -76,7 +75,7 @@ public class TestHelper {
firstOneTimeKey = (new ArrayList<>(generatedKeys.values())).get(aKeyPosition - 1); firstOneTimeKey = (new ArrayList<>(generatedKeys.values())).get(aKeyPosition - 1);
} catch (Exception e) { } catch (Exception e) {
fail("Exception Msg=" + e.getMessage()); assertTrue("Exception Msg=" + e.getMessage(), false);
} }
return firstOneTimeKey; return firstOneTimeKey;
} }

View file

@ -1 +1,8 @@
<manifest package="org.matrix.olm" /> <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.matrix.olm">
<application
android:allowBackup="true"
android:label="@string/app_name">
</application>
</manifest>

View file

@ -114,11 +114,11 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
/** /**
* Return the identity keys (identity and fingerprint keys) in a dictionary.<br> * Return the identity keys (identity and fingerprint keys) in a dictionary.<br>
* Public API for {@link #identityKeysJni()}.<br> * Public API for {@link #identityKeysJni()}.<br>
* Ex:<code> * Ex:<tt>
* { * {
* "curve25519":"Vam++zZPMqDQM6ANKpO/uAl5ViJSHxV9hd+b0/fwRAg", * "curve25519":"Vam++zZPMqDQM6ANKpO/uAl5ViJSHxV9hd+b0/fwRAg",
* "ed25519":"+v8SOlOASFTMrX3MCKBM4iVnYoZ+JIjpNt1fi8Z9O2I" * "ed25519":"+v8SOlOASFTMrX3MCKBM4iVnYoZ+JIjpNt1fi8Z9O2I"
* }</code> * }</tt>
* @return identity keys dictionary if operation succeeds, null otherwise * @return identity keys dictionary if operation succeeds, null otherwise
* @exception OlmException the failure reason * @exception OlmException the failure reason
*/ */
@ -195,14 +195,14 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
/** /**
* Return the "one time keys" in a dictionary.<br> * Return the "one time keys" in a dictionary.<br>
* The number of "one time keys", is specified by {@link #generateOneTimeKeys(int)}<br> * The number of "one time keys", is specified by {@link #generateOneTimeKeys(int)}<br>
* Ex:<code> * Ex:<tt>
* { "curve25519": * { "curve25519":
* { * {
* "AAAABQ":"qefVZd8qvjOpsFzoKSAdfUnJVkIreyxWFlipCHjSQQg", * "AAAABQ":"qefVZd8qvjOpsFzoKSAdfUnJVkIreyxWFlipCHjSQQg",
* "AAAABA":"/X8szMU+p+lsTnr56wKjaLgjTMQQkCk8EIWEAilZtQ8", * "AAAABA":"/X8szMU+p+lsTnr56wKjaLgjTMQQkCk8EIWEAilZtQ8",
* "AAAAAw":"qxNxxFHzevFntaaPdT0fhhO7tc7pco4+xB/5VRG81hA", * "AAAAAw":"qxNxxFHzevFntaaPdT0fhhO7tc7pco4+xB/5VRG81hA",
* } * }
* }</code><br> * }</tt><br>
* Public API for {@link #oneTimeKeysJni()}.<br> * Public API for {@link #oneTimeKeysJni()}.<br>
* Note: these keys are to be published on the server. * Note: these keys are to be published on the server.
* @return one time keys in string dictionary. * @return one time keys in string dictionary.
@ -234,7 +234,7 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
/** /**
* Get the public parts of the unpublished "one time keys" for the account.<br> * Get the public parts of the unpublished "one time keys" for the account.<br>
* The returned data is a JSON-formatted object with the single property * The returned data is a JSON-formatted object with the single property
* <code>curve25519</code>, which is itself an object mapping key id to * <tt>curve25519</tt>, which is itself an object mapping key id to
* base64-encoded Curve25519 key.<br> * base64-encoded Curve25519 key.<br>
* @return byte array containing the one time keys or throw an exception if it fails * @return byte array containing the one time keys or throw an exception if it fails
*/ */
@ -417,99 +417,4 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
* @return the deserialized account * @return the deserialized account
**/ **/
private native long deserializeJni(byte[] aSerializedDataBuffer, byte[] aKeyBuffer); private native long deserializeJni(byte[] aSerializedDataBuffer, byte[] aKeyBuffer);
/**
* Return a pickled account as a bytes buffer.<br>
* The account is serialized and encrypted with aKey.
* In case of failure, an error human readable
* description is provide in aErrorMsg.
* @param aKey encryption key
* @param aErrorMsg error message description
* @return the pickled account as bytes buffer
*/
public byte[] pickle(byte[] aKey, StringBuffer aErrorMsg) {
return serialize(aKey, aErrorMsg);
}
/**
* Loads an account from a pickled bytes buffer.<br>
* See {@link #serialize(byte[], StringBuffer)}
* @param aSerializedData bytes buffer
* @param aKey key used to encrypted
* @exception Exception the exception
*/
public void unpickle(byte[] aSerializedData, byte[] aKey) throws Exception {
deserialize(aSerializedData, aKey);
}
/**
* Generates a new fallback key.
* @throws OlmException exception with a reason.
*/
public void generateFallbackKey() throws OlmException {
try {
generateFallbackKeyJni();
} catch (Exception e) {
throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_GENERATE_FALLBACK_KEY, e.getMessage());
}
}
private native void generateFallbackKeyJni();
/**
* Return the "fallback key" in a dictionary.<br>
* Ex:<code>
* { "curve25519":
* {
* "AAAABQ":"qefVZd8qvjOpsFzoKSAdfUnJVkIreyxWFlipCHjSQQg"
* }
* }</code><br>
* Public API for {@link #fallbackKeyJni()}.<br>
* Note: the key is to be published on the server.
* @return fallback key in string dictionary.
* @exception OlmException the failure reason
*/
public Map<String, Map<String, String>> fallbackKey() throws OlmException {
JSONObject fallbackKeyJsonObj = null;
byte[] fallbackKeyBuffer;
try {
fallbackKeyBuffer = fallbackKeyJni();
} catch (Exception e) {
throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_FALLBACK_KEY, e.getMessage());
}
if( null != fallbackKeyBuffer) {
try {
fallbackKeyJsonObj = new JSONObject(new String(fallbackKeyBuffer, "UTF-8"));
} catch (Exception e) {
Log.e(LOG_TAG, "## fallbackKey(): Exception - Msg=" + e.getMessage());
}
} else {
Log.e(LOG_TAG, "## fallbackKey(): Failure - identityKeysJni()=null");
}
return OlmUtility.toStringMapMap(fallbackKeyJsonObj);
}
private native byte[] fallbackKeyJni();
/**
* Forget about the old fallback key.
*
* This should be called once you are reasonably certain that you will not
* receive any more messages that use the old fallback key (e.g. 5 minutes
* after the new fallback key has been published).
* @throws OlmException the failure reason
**/
public void forgetFallbackKey() throws OlmException {
try {
forgetFallbackKeyJni();
} catch (Exception e) {
throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_FORGET_FALLBACK_KEY, e.getMessage());
}
}
private native void forgetFallbackKeyJni();
} }

View file

@ -35,9 +35,6 @@ public class OlmException extends IOException {
public static final int EXCEPTION_CODE_ACCOUNT_REMOVE_ONE_TIME_KEYS = 105; public static final int EXCEPTION_CODE_ACCOUNT_REMOVE_ONE_TIME_KEYS = 105;
public static final int EXCEPTION_CODE_ACCOUNT_MARK_ONE_KEYS_AS_PUBLISHED = 106; public static final int EXCEPTION_CODE_ACCOUNT_MARK_ONE_KEYS_AS_PUBLISHED = 106;
public static final int EXCEPTION_CODE_ACCOUNT_SIGN_MESSAGE = 107; public static final int EXCEPTION_CODE_ACCOUNT_SIGN_MESSAGE = 107;
public static final int EXCEPTION_CODE_ACCOUNT_GENERATE_FALLBACK_KEY = 108;
public static final int EXCEPTION_CODE_ACCOUNT_FALLBACK_KEY = 109;
public static final int EXCEPTION_CODE_ACCOUNT_FORGET_FALLBACK_KEY = 110;
public static final int EXCEPTION_CODE_CREATE_INBOUND_GROUP_SESSION = 200; public static final int EXCEPTION_CODE_CREATE_INBOUND_GROUP_SESSION = 200;
public static final int EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION = 201; public static final int EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION = 201;
@ -60,7 +57,6 @@ public class OlmException extends IOException {
public static final int EXCEPTION_CODE_SESSION_ENCRYPT_MESSAGE = 404; public static final int EXCEPTION_CODE_SESSION_ENCRYPT_MESSAGE = 404;
public static final int EXCEPTION_CODE_SESSION_DECRYPT_MESSAGE = 405; public static final int EXCEPTION_CODE_SESSION_DECRYPT_MESSAGE = 405;
public static final int EXCEPTION_CODE_SESSION_SESSION_IDENTIFIER = 406; public static final int EXCEPTION_CODE_SESSION_SESSION_IDENTIFIER = 406;
public static final int EXCEPTION_CODE_SESSION_SESSION_DESCRIBE = 407;
public static final int EXCEPTION_CODE_UTILITY_CREATION = 500; public static final int EXCEPTION_CODE_UTILITY_CREATION = 500;
public static final int EXCEPTION_CODE_UTILITY_VERIFY_SIGNATURE = 501; public static final int EXCEPTION_CODE_UTILITY_VERIFY_SIGNATURE = 501;

View file

@ -369,29 +369,4 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
* @return the deserialized session * @return the deserialized session
**/ **/
private native long deserializeJni(byte[] aSerializedData, byte[] aKey); private native long deserializeJni(byte[] aSerializedData, byte[] aKey);
/**
* Return a pickled inbound group session as a bytes buffer.<br>
* The session is serialized and encrypted with aKey.
* In case of failure, an error human readable
* description is provide in aErrorMsg.
* @param aKey encryption key
* @param aErrorMsg error message description
* @return the pickled inbound group session as bytes buffer
*/
public byte[] pickle(byte[] aKey, StringBuffer aErrorMsg) {
return serialize(aKey, aErrorMsg);
}
/**
* Loads an inbound group session from a pickled bytes buffer.<br>
* See {@link #serialize(byte[], StringBuffer)}
* @param aSerializedData bytes buffer
* @param aKey key used to encrypted
* @exception Exception the exception
*/
public void unpickle(byte[] aSerializedData, byte[] aKey) throws Exception {
deserialize(aSerializedData, aKey);
}
} }

View file

@ -46,7 +46,7 @@ public class OlmManager {
* @return the library version * @return the library version
*/ */
public String getVersion() { public String getVersion() {
return BuildConfig.OLM_VERSION; return BuildConfig.VERSION_NAME;
} }
/** /**

View file

@ -293,28 +293,4 @@ public class OlmOutboundGroupSession extends CommonSerializeUtils implements Ser
**/ **/
private native long deserializeJni(byte[] aSerializedData, byte[] aKey); private native long deserializeJni(byte[] aSerializedData, byte[] aKey);
/**
* Return a pickled outbound group session as a bytes buffer.<br>
* The session is serialized and encrypted with aKey.
* In case of failure, an error human readable
* description is provide in aErrorMsg.
* @param aKey encryption key
* @param aErrorMsg error message description
* @return the pickled outbound group session as bytes buffer
*/
public byte[] pickle(byte[] aKey, StringBuffer aErrorMsg) {
return serialize(aKey, aErrorMsg);
}
/**
* Loads an outbound group session from a pickled bytes buffer.<br>
* See {@link #serialize(byte[], StringBuffer)}
* @param aSerializedData bytes buffer
* @param aKey key used to encrypted
* @exception Exception the exception
*/
public void unpickle(byte[] aSerializedData, byte[] aKey) throws Exception {
deserialize(aSerializedData, aKey);
}
} }

View file

@ -106,16 +106,6 @@ public class OlmSAS {
return null; return null;
} }
public String calculateMacFixedBase64(String message, String info) throws OlmException {
try {
byte[] bytes = calculateMacFixedBase64Jni(message.getBytes("UTF-8"), info.getBytes("UTF-8"));
if (bytes != null) return new String(bytes, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new OlmException(OlmException.EXCEPTION_CODE_SAS_ERROR, e.getMessage());
}
return null;
}
public String calculateMacLongKdf(String message, String info) throws OlmException { public String calculateMacLongKdf(String message, String info) throws OlmException {
try { try {
byte[] bytes = calculateMacLongKdfJni(message.getBytes("UTF-8"), info.getBytes("UTF-8")); byte[] bytes = calculateMacLongKdfJni(message.getBytes("UTF-8"), info.getBytes("UTF-8"));
@ -150,8 +140,6 @@ public class OlmSAS {
private native byte[] calculateMacJni(byte[] message, byte[] info); private native byte[] calculateMacJni(byte[] message, byte[] info);
private native byte[] calculateMacFixedBase64Jni(byte[] message, byte[] info);
private native byte[] calculateMacLongKdfJni(byte[] message, byte[] info); private native byte[] calculateMacLongKdfJni(byte[] message, byte[] info);
/** /**

View file

@ -223,23 +223,6 @@ public class OlmSession extends CommonSerializeUtils implements Serializable {
*/ */
private native byte[] getSessionIdentifierJni(); private native byte[] getSessionIdentifierJni();
public String sessionDescribe() throws OlmException {
try {
byte[] buffer = olmSessionDescribeJni();
if (null != buffer) {
return new String(buffer, "UTF-8");
}
} catch (Exception e) {
Log.e(LOG_TAG, "## sessionDescribe(): " + e.getMessage());
throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_SESSION_DESCRIBE, e.getMessage());
}
return null;
}
private native byte[] olmSessionDescribeJni();
/** /**
* Checks if the PRE_KEY({@link OlmMessage#MESSAGE_TYPE_PRE_KEY}) message is for this in-bound session.<br> * Checks if the PRE_KEY({@link OlmMessage#MESSAGE_TYPE_PRE_KEY}) message is for this in-bound session.<br>
* This API may be used to process a "m.room.encrypted" event when type = 1 (PRE_KEY). * This API may be used to process a "m.room.encrypted" event when type = 1 (PRE_KEY).
@ -465,30 +448,5 @@ public class OlmSession extends CommonSerializeUtils implements Serializable {
* @return the deserialized session * @return the deserialized session
**/ **/
private native long deserializeJni(byte[] aSerializedData, byte[] aKey); private native long deserializeJni(byte[] aSerializedData, byte[] aKey);
/**
* Return a pickled session as a bytes buffer.<br>
* The session is serialized and encrypted with aKey.
* In case of failure, an error human readable
* description is provide in aErrorMsg.
* @param aKey encryption key
* @param aErrorMsg error message description
* @return the pickled session as bytes buffer
*/
public byte[] pickle(byte[] aKey, StringBuffer aErrorMsg) {
return serialize(aKey, aErrorMsg);
}
/**
* Loads a session from a pickled bytes buffer.<br>
* See {@link #serialize(byte[], StringBuffer)}
* @param aSerializedData bytes buffer
* @param aKey key used to encrypted
* @exception Exception the exception
*/
public void unpickle(byte[] aSerializedData, byte[] aKey) throws Exception {
deserialize(aSerializedData, aKey);
}
} }

View file

@ -442,161 +442,6 @@ JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(markOneTimeKeysAsPublishedJni)(JNIEnv *env,
} }
} }
/**
* Generate "fallback key".
* An exception is thrown if the operation fails.
**/
JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(generateFallbackKeyJni)(JNIEnv *env, jobject thiz)
{
const char* errorMessage = NULL;
OlmAccount *accountPtr = getAccountInstanceId(env, thiz);
if (!accountPtr)
{
LOGE("## generateFallbackKeyJni(): failure - invalid Account ptr");
errorMessage = "invalid Account ptr";
}
else
{
// keys memory allocation
size_t randomLength = olm_account_generate_fallback_key_random_length(accountPtr);
LOGD("## generateFallbackKeyJni(): randomLength=%lu", static_cast<long unsigned int>(randomLength));
uint8_t *randomBufferPtr = NULL;
if ((0 != randomLength) && !setRandomInBuffer(env, &randomBufferPtr, randomLength))
{
LOGE("## generateFallbackKeyJni(): failure - random buffer init");
errorMessage = "random buffer init";
}
else
{
LOGD("## generateFallbackKeyJni(): accountPtr =%p", accountPtr);
// retrieve key pairs in keysBytesPtr
size_t result = olm_account_generate_fallback_key(accountPtr, (void*)randomBufferPtr, randomLength);
if (result == olm_error())
{
errorMessage = olm_account_last_error(accountPtr);
LOGE("## generateFallbackKeyJni(): failure - error generating fallback keys Msg=%s", errorMessage);
}
else
{
LOGD("## generateFallbackKeyJni(): success - result=%lu", static_cast<long unsigned int>(result));
}
}
if (randomBufferPtr)
{
memset(randomBufferPtr, 0, randomLength);
free(randomBufferPtr);
}
}
if (errorMessage)
{
env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
}
}
/**
* Get "fallback key".<br>
* Return the public parts of the unpublished "fallback key" for the account
* @return a valid byte array if operation succeed, null otherwise
**/
JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(fallbackKeyJni)(JNIEnv *env, jobject thiz)
{
const char* errorMessage = NULL;
jbyteArray byteArrayRetValue = NULL;
OlmAccount* accountPtr = getAccountInstanceId(env, thiz);
LOGD("## fallbackKeyJni(): IN");
if (!accountPtr)
{
LOGE("## fallbackKeyJni(): failure - invalid Account ptr");
errorMessage = "invalid Account ptr";
}
else
{
// keys memory allocation
size_t keysLength = olm_account_unpublished_fallback_key_length(accountPtr);
uint8_t *keysBytesPtr = (uint8_t *)malloc(keysLength*sizeof(uint8_t));
if (!keysBytesPtr)
{
LOGE("## fallbackKeyJni(): failure - fallback key OOM");
errorMessage = "fallback key OOM";
}
else
{
// retrieve key pairs in keysBytesPtr
size_t keysResult = olm_account_unpublished_fallback_key(accountPtr, keysBytesPtr, keysLength);
if (keysResult == olm_error()) {
LOGE("## fallbackKeyJni(): failure - error getting fallback key Msg=%s",(const char *)olm_account_last_error(accountPtr));
errorMessage = (const char *)olm_account_last_error(accountPtr);
}
else
{
// allocate the byte array to be returned to java
byteArrayRetValue = env->NewByteArray(keysLength);
if (!byteArrayRetValue)
{
LOGE("## fallbackKeyJni(): failure - return byte array OOM");
errorMessage = "return byte array OOM";
}
else
{
env->SetByteArrayRegion(byteArrayRetValue, 0/*offset*/, keysLength, (const jbyte*)keysBytesPtr);
LOGD("## fallbackKeyJni(): success");
}
}
free(keysBytesPtr);
}
}
if (errorMessage)
{
env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
}
return byteArrayRetValue;
}
/**
* Forget about the old fallback key.
*
* This should be called once you are reasonably certain that you will not
* receive any more messages that use the old fallback key (e.g. 5 minutes
* after the new fallback key has been published).
**/
JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(forgetFallbackKeyJni)(JNIEnv *env, jobject thiz)
{
const char* errorMessage = NULL;
OlmAccount *accountPtr = getAccountInstanceId(env, thiz);
if (!accountPtr)
{
LOGE("## forgetFallbackKeyJni(): failure - invalid Account ptr");
errorMessage = "invalid Account ptr";
}
else
{
olm_account_forget_old_fallback_key(accountPtr);
}
if (errorMessage)
{
env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
}
}
/** /**
* Sign a message with the ed25519 key (fingerprint) for this account.<br> * Sign a message with the ed25519 key (fingerprint) for this account.<br>
* The signed message is returned by the function. * The signed message is returned by the function.

View file

@ -42,11 +42,6 @@ JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(generateOneTimeKeysJni)(JNIEnv *env, jobject
JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(removeOneTimeKeysJni)(JNIEnv *env, jobject thiz, jlong aNativeOlmSessionId); JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(removeOneTimeKeysJni)(JNIEnv *env, jobject thiz, jlong aNativeOlmSessionId);
JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(markOneTimeKeysAsPublishedJni)(JNIEnv *env, jobject thiz); JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(markOneTimeKeysAsPublishedJni)(JNIEnv *env, jobject thiz);
// fallback keys
JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(generateFallbackKeyJni)(JNIEnv *env, jobject thiz);
JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(fallbackKeyJni)(JNIEnv *env, jobject thiz);
JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(forgetFallbackKeyJni)(JNIEnv *env, jobject thiz);
// signing // signing
JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(signMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aMessage); JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(signMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aMessage);

View file

@ -309,86 +309,6 @@ JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(calculateMacJni)(JNIEnv *env, jobject thiz
return returnValue; return returnValue;
} }
JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(calculateMacFixedBase64Jni)(JNIEnv *env, jobject thiz,jbyteArray messageBuffer,jbyteArray infoBuffer) {
LOGD("## calculateMacFixedBase64Jni(): IN");
const char* errorMessage = NULL;
jbyteArray returnValue = 0;
OlmSAS* sasPtr = getOlmSasInstanceId(env, thiz);
jbyte *messagePtr = NULL;
jboolean messageWasCopied = JNI_FALSE;
jbyte *infoPtr = NULL;
jboolean infoWasCopied = JNI_FALSE;
if (!sasPtr)
{
LOGE("## calculateMacFixedBase64Jni(): failure - invalid SAS ptr=NULL");
errorMessage = "invalid SAS ptr=NULL";
} else if(!messageBuffer) {
LOGE("## calculateMacFixedBase64Jni(): failure - invalid message");
errorMessage = "invalid info";
}
else if (!(messagePtr = env->GetByteArrayElements(messageBuffer, &messageWasCopied)))
{
LOGE(" ## calculateMacFixedBase64Jni(): failure - message JNI allocation OOM");
errorMessage = "message JNI allocation OOM";
}
else if (!(infoPtr = env->GetByteArrayElements(infoBuffer, &infoWasCopied)))
{
LOGE(" ## calculateMacFixedBase64Jni(): failure - info JNI allocation OOM");
errorMessage = "info JNI allocation OOM";
} else {
size_t infoLength = (size_t)env->GetArrayLength(infoBuffer);
size_t messageLength = (size_t)env->GetArrayLength(messageBuffer);
size_t macLength = olm_sas_mac_length(sasPtr);
void *macPtr = malloc(macLength*sizeof(uint8_t));
size_t result = olm_sas_calculate_mac_fixed_base64(sasPtr,messagePtr,messageLength,infoPtr,infoLength,macPtr,macLength);
if (result == olm_error())
{
errorMessage = (const char *)olm_sas_last_error(sasPtr);
LOGE("## calculateMacFixedBase64Jni(): failure - error calculating SAS mac Msg=%s", errorMessage);
}
else
{
returnValue = env->NewByteArray(macLength);
env->SetByteArrayRegion(returnValue, 0 , macLength, (jbyte*)macPtr);
}
if (macPtr) {
free(macPtr);
}
}
// free alloc
if (infoPtr)
{
if (infoWasCopied)
{
memset(infoPtr, 0, (size_t)env->GetArrayLength(infoBuffer));
}
env->ReleaseByteArrayElements(infoBuffer, infoPtr, JNI_ABORT);
}
if (messagePtr)
{
if (messageWasCopied)
{
memset(messagePtr, 0, (size_t)env->GetArrayLength(messageBuffer));
}
env->ReleaseByteArrayElements(messageBuffer, messagePtr, JNI_ABORT);
}
if (errorMessage)
{
env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
}
return returnValue;
}
JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(calculateMacLongKdfJni)(JNIEnv *env, jobject thiz,jbyteArray messageBuffer,jbyteArray infoBuffer) { JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(calculateMacLongKdfJni)(JNIEnv *env, jobject thiz,jbyteArray messageBuffer,jbyteArray infoBuffer) {
LOGD("## calculateMacLongKdfJni(): IN"); LOGD("## calculateMacLongKdfJni(): IN");
const char* errorMessage = NULL; const char* errorMessage = NULL;

View file

@ -32,7 +32,6 @@ JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(getPubKeyJni)(JNIEnv *env, jobject thiz);
JNIEXPORT void OLM_SAS_FUNC_DEF(setTheirPubKey)(JNIEnv *env, jobject thiz,jbyteArray pubKey); JNIEXPORT void OLM_SAS_FUNC_DEF(setTheirPubKey)(JNIEnv *env, jobject thiz,jbyteArray pubKey);
JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(generateShortCodeJni)(JNIEnv *env, jobject thiz, jbyteArray infoStringBytes, jint byteNb); JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(generateShortCodeJni)(JNIEnv *env, jobject thiz, jbyteArray infoStringBytes, jint byteNb);
JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(calculateMacJni)(JNIEnv *env, jobject thiz, jbyteArray messageBuffer, jbyteArray infoBuffer); JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(calculateMacJni)(JNIEnv *env, jobject thiz, jbyteArray messageBuffer, jbyteArray infoBuffer);
JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(calculateMacFixedBase64Jni)(JNIEnv *env, jobject thiz, jbyteArray messageBuffer, jbyteArray infoBuffer);
JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(calculateMacLongKdfJni)(JNIEnv *env, jobject thiz, jbyteArray messageBuffer, jbyteArray infoBuffer); JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(calculateMacLongKdfJni)(JNIEnv *env, jobject thiz, jbyteArray messageBuffer, jbyteArray infoBuffer);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -798,58 +798,6 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(getSessionIdentifierJni)(JNIEnv *env,
return returnValue; return returnValue;
} }
JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(olmSessionDescribeJni(JNIEnv *env, jobject thiz))
{
const char* errorMessage = NULL;
jbyteArray returnValue = 0;
LOGD("## olmSessionDescribeJni(): IN ");
OlmSession *sessionPtr = getSessionInstanceId(env, thiz);
if (!sessionPtr)
{
LOGE("## olmSessionDescribeJni(): failure - invalid Session ptr=NULL");
errorMessage = "invalid Session ptr=NULL";
}
else
{
int maxLength = 600;
char* describePtr = NULL;
describePtr = (char*) malloc(maxLength * sizeof *describePtr);
if (!describePtr)
{
LOGE("## olmSessionDescribeJni(): failure - describe allocation OOM");
errorMessage = "describe allocation OOM";
}
else
{
olm_session_describe(sessionPtr, describePtr, maxLength);
int length = strlen(describePtr);
if (length == 0)
{
LOGE("## olmSessionDescribeJni(): failure - get session describe");
}
else
{
LOGD("## olmSessionDescribeJni(): success - describe=%.*s", (char*)describePtr);
returnValue = env->NewByteArray(length);
env->SetByteArrayRegion(returnValue, 0, length, (jbyte*)describePtr);
}
free(describePtr);
}
}
if (errorMessage)
{
env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
}
return returnValue;
}
/** /**
* Serialize and encrypt session instance.<br> * Serialize and encrypt session instance.<br>
* An exception is thrown if the operation fails. * An exception is thrown if the operation fails.

View file

@ -47,7 +47,6 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobjec
JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jobject aEncryptedMsg); JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jobject aEncryptedMsg);
JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(getSessionIdentifierJni)(JNIEnv *env, jobject thiz); JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(getSessionIdentifierJni)(JNIEnv *env, jobject thiz);
JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(olmSessionDescribeJni)(JNIEnv *env, jobject thiz);
// serialization // serialization
JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKey); JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKey);

View file

@ -0,0 +1,3 @@
<resources>
<string name="app_name">OlmSdk</string>
</resources>

View file

@ -1,4 +1,4 @@
MAJOR := 3 MAJOR := 3
MINOR := 2 MINOR := 1
PATCH := 16 PATCH := 4

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 48 KiB

View file

@ -1,39 +0,0 @@
lifelinestyle ::solid
participantspacing 10
participant :0 " " as p0
lifelinestyle p0 #white
actor "Alice" as A
participant :0 " " as p1
lifelinestyle p1 #white
actor "Bob" as B
participant :0 " " as p2
lifelinestyle p2 #white
parallel
box over A: ""//R[0]//"" = ""HKDF(0, //S//)""
box over B: ""//R[0]//"" = ""HKDF(0, //S//)""
parallel off
box over A: generate new ratchet keypair ""//T[0]//""
A->B: ""//R[0]//(//msg0//)"", ""//T[0]//""
A->B: ""//R[0]//(//msg1//)"", ""//T[0]//""
A->B: ""//R[0]//(//msg2//)"", ""//T[0]//""
box over B: generate new ratchet keypair ""//T[1]//""
box over B: ""//R[1]//"" = ""HKDF(//R[0]//, DH(//T[1]//, //T[0]//))""
B->A: ""//R[1]//(//msg3//)"", ""//T[1]//""
box over A: ""//R[1]//"" = ""HKDF(//R[0]//, DH(//T[0]//, //T[1]//))""
B->A: ""//R[1]//(//msg4//)"", ""//T[1]//""
B->(13)A: ""//R[1]//(//msg5//)"", ""//T[1]//""
space -14
box over A: generate new ratchet keypair ""//T[2]//""
box over A: ""//R[2]//"" = ""HKDF(//R[1]//, DH(//T[2]//, //T[1]//))""
A->(3)B: ""//R[2]//(//msg6//)"", ""//T[2]//""
box over B: ""//R[2]//"" = ""HKDF(//R[1]//, DH(//T[1]//, //T[2]//))""
box over p0,p2 #EDF2AE:<size:10>where:\n ""//S//"" is the shared secret derived from the 3ECDH exchange\n ""//R[n]//"" is a root key\n ""//T[n]//"" is a ratchet keypair\n ""HKDF(//salt//, //key//)"" means performing an HMAC-based key derivation with a salt value of ""//salt//"" and input key material of ""//key//""\n ""DH(//k1//, //k2//)"" means performing Diffie-Hellman with the private half of ""//k1//"" and the public half of ""//k2//""\n ""//R[n]//(//msg//)"" means a message encrypted with a key derived from root key ""//R[n]//""

Binary file not shown.

File diff suppressed because it is too large Load diff

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View file

@ -41,26 +41,26 @@ advanced as follows:
\begin{aligned} \begin{aligned}
R_{i,0} &= R_{i,0} &=
\begin{cases} \begin{cases}
H_0\left(R_{2^{24}(n-1),0}\right) &\text{if }\exists n | i = 2^{24}n\\ H_0\left(R_{2^24(n-1),0}\right) &\text{if }\exists n | i = 2^24n\\
R_{i-1,0} &\text{otherwise} R_{i-1,0} &\text{otherwise}
\end{cases}\\ \end{cases}\\
R_{i,1} &= R_{i,1} &=
\begin{cases} \begin{cases}
H_1\left(R_{2^{24}(n-1),0}\right) &\text{if }\exists n | i = 2^{24}n\\ H_1\left(R_{2^24(n-1),0}\right) &\text{if }\exists n | i = 2^24n\\
H_1\left(R_{2^{16}(m-1),1}\right) &\text{if }\exists m | i = 2^{16}m\\ H_1\left(R_{2^16(m-1),1}\right) &\text{if }\exists m | i = 2^16m\\
R_{i-1,1} &\text{otherwise} R_{i-1,1} &\text{otherwise}
\end{cases}\\ \end{cases}\\
R_{i,2} &= R_{i,2} &=
\begin{cases} \begin{cases}
H_2\left(R_{2^{24}(n-1),0}\right) &\text{if }\exists n | i = 2^{24}n\\ H_2\left(R_{2^24(n-1),0}\right) &\text{if }\exists n | i = 2^24n\\
H_2\left(R_{2^{16}(m-1),1}\right) &\text{if }\exists m | i = 2^{16}m\\ H_2\left(R_{2^16(m-1),1}\right) &\text{if }\exists m | i = 2^16m\\
H_2\left(R_{2^8(p-1),2}\right) &\text{if }\exists p | i = 2^8p\\ H_2\left(R_{2^8(p-1),2}\right) &\text{if }\exists p | i = 2^8p\\
R_{i-1,2} &\text{otherwise} R_{i-1,2} &\text{otherwise}
\end{cases}\\ \end{cases}\\
R_{i,3} &= R_{i,3} &=
\begin{cases} \begin{cases}
H_3\left(R_{2^{24}(n-1),0}\right) &\text{if }\exists n | i = 2^{24}n\\ H_3\left(R_{2^24(n-1),0}\right) &\text{if }\exists n | i = 2^24n\\
H_3\left(R_{2^{16}(m-1),1}\right) &\text{if }\exists m | i = 2^{16}m\\ H_3\left(R_{2^16(m-1),1}\right) &\text{if }\exists m | i = 2^16m\\
H_3\left(R_{2^8(p-1),2}\right) &\text{if }\exists p | i = 2^8p\\ H_3\left(R_{2^8(p-1),2}\right) &\text{if }\exists p | i = 2^8p\\
H_3\left(R_{i-1,3}\right) &\text{otherwise} H_3\left(R_{i-1,3}\right) &\text{otherwise}
\end{cases} \end{cases}
@ -109,7 +109,7 @@ discriminate between sessions.
### Sharing session data ### Sharing session data
To allow other participants in the conversation to decrypt messages, the To allow other participants in the conversation to decrypt messages, the
session data is formatted as described in [Session-sharing format](#session-sharing-format). It is then session data is formatted as described in [Session-sharing format](#Session-sharing-format). It is then
shared with other participants in the conversation via a secure peer-to-peer shared with other participants in the conversation via a secure peer-to-peer
channel (such as that provided by [Olm][]). channel (such as that provided by [Olm][]).
@ -182,13 +182,9 @@ but the decision of which ratchet states to cache is left to the application.
## Data exchange formats ## Data exchange formats
### Session sharing format ### Session-sharing format
This format is used for the initial sharing of a Megolm session with other The Megolm key-sharing format is as follows:
group participants who need to be able to read messages encrypted by this
session.
The session sharing format is as follows:
``` ```
+---+----+--------+--------+--------+--------+------+-----------+ +---+----+--------+--------+--------+--------+------+-----------+
@ -206,33 +202,6 @@ part of the Ed25519 keypair $`K`$.
The data is then signed using the Ed25519 keypair, and the 64-byte signature is The data is then signed using the Ed25519 keypair, and the 64-byte signature is
appended. appended.
### Session export format
Once the session is initially shared with the group participants, each
participant needs to retain a copy of the session if they want to maintain
their ability to decrypt messages encrypted with that session.
For forward-secrecy purposes, a participant may choose to store a ratcheted
version of the session. But since the ratchet index is covered by the
signature, this would invalidate the signature. So we define a similar format,
called the *session export format*, which is identical to the [session sharing
format](#session-sharing-format) except for dropping the signature.
The Megolm session export format is thus as follows:
```
+---+----+--------+--------+--------+--------+------+
| V | i | R(i,0) | R(i,1) | R(i,2) | R(i,3) | Kpub |
+---+----+--------+--------+--------+--------+------+
0 1 5 37 69 101 133 165 bytes
```
The version byte, ``V``, is ``"\x01"``.
This is followed by the ratchet index, $`i`$, which is encoded as a
big-endian 32-bit integer; the ratchet values $`R_{i,j}`$; and the public
part of the Ed25519 keypair $`K`$.
### Message format ### Message format
Megolm messages consist of a one byte version, followed by a variable length Megolm messages consist of a one byte version, followed by a variable length

View file

@ -75,7 +75,7 @@ S = \operatorname{ECDH}\left(I_A,E_B\right)\;\parallel\;
If keys are unsigned, a forger can make up values of $`E_A`$ and If keys are unsigned, a forger can make up values of $`E_A`$ and
$`E_B`$, and construct a transcript of a conversation which looks like it $`E_B`$, and construct a transcript of a conversation which looks like it
was between Alice and Bob. Alice and Bob can therefore plausibly deny their was between Alice and Bob. Alice and Bob can therefore plausibly deny their
participation in any conversation even if they are both forced to divulge their partition in any conversation even if they are both forced to divulge their
private identity keys, since it is impossible to prove that the transcript was private identity keys, since it is impossible to prove that the transcript was
a conversation between the two of them, rather than constructed by a forger. a conversation between the two of them, rather than constructed by a forger.

View file

@ -1,12 +1,12 @@
#!/usr/bin/env python3 #!/usr/bin/env python
import sys import sys
import re import re
import json import json
expr = re.compile(r"(_*olm_[^( ]*)\(") expr = re.compile(r"(olm_[^( ]*)\(")
exports = {'_free', '_malloc'} exports = set()
for f in sys.argv[1:]: for f in sys.argv[1:]:
with open(f) as fp: with open(f) as fp:

View file

@ -1,60 +0,0 @@
{
"nodes": {
"flake-utils": {
"locked": {
"lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1664871473,
"narHash": "sha256-1LzbW6G6Uz8akWiOdlIi435GAm1ct5jF5tovw/9to0o=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b7a6fde153d9470afdb6aa1da51c4117f03b84ed",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"npmlock2nix": {
"flake": false,
"locked": {
"lastModified": 1654775747,
"narHash": "sha256-9pXHDpIjmsK5390wmpGHu9aA4QOPpegPBvThHeBlef4=",
"owner": "nix-community",
"repo": "npmlock2nix",
"rev": "5c4f247688fc91d665df65f71c81e0726621aaa8",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "npmlock2nix",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs",
"npmlock2nix": "npmlock2nix"
}
}
},
"root": "root",
"version": 7
}

View file

@ -1,40 +0,0 @@
{
description = "An implementation of the Double Ratchet cryptographic ratchet";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
# We can't use the current stable release because of
# https://github.com/emscripten-core/emscripten/issues/16913
inputs.flake-utils.url = "github:numtide/flake-utils";
inputs.npmlock2nix = {
url = "github:nix-community/npmlock2nix";
flake = false;
};
outputs = { self, nixpkgs, flake-utils, npmlock2nix }:
let
localOverlay = import ./nix/overlay.nix;
pkgsForSystem = system: import nixpkgs {
inherit system;
overlays = [
(final: prev: {
npmlock2nix = final.callPackage npmlock2nix {};
node_modules = final.npmlock2nix.node_modules { src = ./javascript; };
})
localOverlay
];
};
in (
# some systems cause issues, e.g. i686-linux is unsupported by gradle,
# which causes "nix flake check" to fail. Investigate more later, but for
# now, we will just allow x86_64-linux
flake-utils.lib.eachSystem [ "x86_64-linux" "x86_64-darwin" "aarch64-darwin" ] (system: rec {
legacyPackages = pkgsForSystem system;
checks = {
inherit (legacyPackages) olm-gcc-cmake olm-clang-cmake olm-gcc-make;
};
packages = {
javascript = legacyPackages.olm-javascript;
};
}
));
}

View file

@ -11,6 +11,4 @@ int main(int argc, const char *argv[]) {
decode_message(*reader, message_buffer, message_length, 8); decode_message(*reader, message_buffer, message_length, 8);
free(message_buffer); free(message_buffer);
delete reader; delete reader;
return EXIT_SUCCESS;
} }

View file

@ -3,10 +3,11 @@
#include "fuzzing.hh" #include "fuzzing.hh"
int main(int argc, const char *argv[]) { int main(int argc, const char *argv[]) {
size_t ignored;
if (argc <= 3) { if (argc <= 3) {
const char * message = "Usage: decrypt: <session_key> <session_file>" const char * message = "Usage: decrypt: <session_key> <session_file>"
" <message_type>\n"; " <message_type>\n";
(void)write(STDERR_FILENO, message, strlen(message)); ignored = write(STDERR_FILENO, message, strlen(message));
exit(3); exit(3);
} }
@ -58,12 +59,7 @@ int main(int argc, const char *argv[]) {
) )
); );
(void)write(STDOUT_FILENO, plaintext, length); ignored = write(STDOUT_FILENO, plaintext, length);
(void)write(STDOUT_FILENO, "\n", 1); ignored = write(STDOUT_FILENO, "\n", 1);
return ignored;
free(session_buffer);
free(message_buffer);
free(tmp_buffer);
return EXIT_SUCCESS;
} }

View file

@ -0,0 +1,73 @@
#include "olm/olm.hh"
#include "fuzzing.hh"
int main(int argc, const char *argv[]) {
size_t ignored;
if (argc <= 2) {
const char * message = "Usage: decrypt <pickle_key> <group_session>\n";
ignored = write(STDERR_FILENO, message, strlen(message));
exit(3);
}
const char * key = argv[1];
size_t key_length = strlen(key);
int session_fd = check_errno(
"Error opening session file", open(argv[2], O_RDONLY)
);
uint8_t *session_buffer;
ssize_t session_length = check_errno(
"Error reading session file", read_file(session_fd, &session_buffer)
);
int message_fd = STDIN_FILENO;
uint8_t * message_buffer;
ssize_t message_length = check_errno(
"Error reading message file", read_file(message_fd, &message_buffer)
);
uint8_t * tmp_buffer = (uint8_t *) malloc(message_length);
memcpy(tmp_buffer, message_buffer, message_length);
uint8_t session_memory[olm_inbound_group_session_size()];
OlmInboundGroupSession * session = olm_inbound_group_session(session_memory);
check_error(
olm_inbound_group_session_last_error,
session,
"Error unpickling session",
olm_unpickle_inbound_group_session(
session, key, key_length, session_buffer, session_length
)
);
size_t max_length = check_error(
olm_inbound_group_session_last_error,
session,
"Error getting plaintext length",
olm_group_decrypt_max_plaintext_length(
session, tmp_buffer, message_length
)
);
uint8_t plaintext[max_length];
uint32_t ratchet_index;
size_t length = check_error(
olm_inbound_group_session_last_error,
session,
"Error decrypting message",
olm_group_decrypt(
session,
message_buffer, message_length,
plaintext, max_length, &ratchet_index
)
);
ignored = write(STDOUT_FILENO, plaintext, length);
ignored = write(STDOUT_FILENO, "\n", 1);
return ignored;
}

View file

@ -0,0 +1,14 @@
#include "olm/account.hh"
#include "fuzzing.hh"
int main(int argc, const char *argv[]) {
int pickle_fd = STDIN_FILENO;
uint8_t * pickle_buffer;
ssize_t pickle_length = check_errno(
"Error reading pickle file", read_file(pickle_fd, &pickle_buffer)
);
olm::Account * account = new olm::Account;
unpickle(pickle_buffer, pickle_buffer + pickle_length, *account);
free(pickle_buffer);
delete account;
}

View file

@ -11,6 +11,4 @@ int main(int argc, const char *argv[]) {
unpickle(pickle_buffer, pickle_buffer + pickle_length, *session); unpickle(pickle_buffer, pickle_buffer + pickle_length, *session);
free(pickle_buffer); free(pickle_buffer);
delete session; delete session;
return EXIT_SUCCESS;
} }

View file

@ -15,43 +15,28 @@ ssize_t read_file(
uint8_t **buffer uint8_t **buffer
) { ) {
size_t buffer_size = 4096; size_t buffer_size = 4096;
size_t buffer_pos = 0;
uint8_t * current_buffer = (uint8_t *) malloc(buffer_size); uint8_t * current_buffer = (uint8_t *) malloc(buffer_size);
if (!current_buffer) return -1; if (current_buffer == NULL) return -1;
size_t buffer_pos = 0;
while (1) { while (1) {
ssize_t count = read( ssize_t count = read(
fd, current_buffer + buffer_pos, buffer_size - buffer_pos fd, current_buffer + buffer_pos, buffer_size - buffer_pos
); );
if (count < 0) break;
if (count < 0) break; // A read error happened, so just fail immediately.
if (count == 0) { if (count == 0) {
// Nothing more left to read. We downsize the buffer to fit the uint8_t * return_buffer = (uint8_t *) realloc(current_buffer, buffer_pos);
// data exactly, unless no data was read at all, in which case we if (return_buffer == NULL) break;
// skip the downsizing. *buffer = return_buffer;
if (buffer_pos != 0) {
current_buffer = (uint8_t *) realloc(current_buffer, buffer_pos);
if (!current_buffer) break;
}
// The read was successful so we return the allocated buffer.
*buffer = current_buffer;
return buffer_pos; return buffer_pos;
} }
buffer_pos += count; buffer_pos += count;
// We've reached capacity, so enlarge the buffer.
if (buffer_pos == buffer_size) { if (buffer_pos == buffer_size) {
buffer_size *= 2; buffer_size *= 2;
uint8_t * new_buffer = (uint8_t *) realloc(current_buffer, buffer_size); uint8_t * new_buffer = (uint8_t *) realloc(current_buffer, buffer_size);
if (!new_buffer) break; if (new_buffer == NULL) break;
current_buffer = new_buffer; current_buffer = new_buffer;
} }
} }
free(current_buffer); free(current_buffer);
return -1; return -1;
} }
@ -77,12 +62,13 @@ size_t check_error(
) { ) {
if (value == olm_error()) { if (value == olm_error()) {
const char * olm_message = f(object); const char * olm_message = f(object);
(void)write(STDERR_FILENO, message, strlen(message)); ssize_t ignored;
(void)write(STDERR_FILENO, ": ", 2); ignored = write(STDERR_FILENO, message, strlen(message));
(void)write(STDERR_FILENO, olm_message, strlen(olm_message)); ignored = write(STDERR_FILENO, ": ", 2);
(void)write(STDERR_FILENO, "\n", 1); ignored = write(STDERR_FILENO, olm_message, strlen(olm_message));
ignored = write(STDERR_FILENO, "\n", 1);
exit(2); exit(2);
return ignored;
} }
return value; return value;
} }

View file

@ -1,10 +0,0 @@
# Directory structure
- `fuzzers/`: Sources for the fuzzing harnesses.
- `corpora/`: Contains the fuzzing corpora and assorted tools. The corpora are
filed under a directory with the same name as the fuzzing harness. Each of
those directories also contains the following:
- `in/`: Contains the actual corpus test cases.
- `tools/`: Any tools useful for that particular harness. A good example
would be a binary which generates seed test cases.

View file

@ -1,102 +0,0 @@
#include "olm/olm.hh"
#include "fuzzing.hh"
#ifndef __AFL_FUZZ_TESTCASE_LEN
ssize_t fuzz_len;
#define __AFL_FUZZ_TESTCASE_LEN fuzz_len
unsigned char fuzz_buf[1024000];
#define __AFL_FUZZ_TESTCASE_BUF fuzz_buf
#define __AFL_FUZZ_INIT() void sync(void);
#define __AFL_LOOP(x) ((fuzz_len = read(0, fuzz_buf, sizeof(fuzz_buf))) > 0 ? 1 : 0)
#define __AFL_INIT() sync()
#endif
__AFL_FUZZ_INIT();
int main(int argc, const char *argv[]) {
if (argc <= 2) {
const char * message = "Usage: decrypt <pickle_key> <group_session>\n";
(void)write(STDERR_FILENO, message, strlen(message));
exit(3);
}
const char * key = argv[1];
size_t key_length = strlen(key);
int session_fd = check_errno(
"Error opening session file", open(argv[2], O_RDONLY)
);
uint8_t *session_buffer;
ssize_t session_length = check_errno(
"Error reading session file", read_file(session_fd, &session_buffer)
);
uint8_t session_memory[olm_inbound_group_session_size()];
OlmInboundGroupSession * session = olm_inbound_group_session(session_memory);
check_error(
olm_inbound_group_session_last_error,
session,
"Error unpickling session",
olm_unpickle_inbound_group_session(
session, key, key_length, session_buffer, session_length
)
);
#ifdef __AFL_HAVE_MANUAL_CONTROL
__AFL_INIT();
#endif
size_t test_case_buf_len = 1024;
uint8_t * message_buffer = (uint8_t *) malloc(test_case_buf_len);
uint8_t * tmp_buffer = (uint8_t *) malloc(test_case_buf_len);
while (__AFL_LOOP(10000)) {
size_t message_length = __AFL_FUZZ_TESTCASE_LEN;
if (message_length > test_case_buf_len) {
message_buffer = (uint8_t *)realloc(message_buffer, message_length);
tmp_buffer = (uint8_t *)realloc(tmp_buffer, message_length);
if (!message_buffer || !tmp_buffer) return 1;
}
memcpy(message_buffer, __AFL_FUZZ_TESTCASE_BUF, message_length);
memcpy(tmp_buffer, message_buffer, message_length);
size_t max_length = check_error(
olm_inbound_group_session_last_error,
session,
"Error getting plaintext length",
olm_group_decrypt_max_plaintext_length(
session, tmp_buffer, message_length
)
);
uint8_t plaintext[max_length];
uint32_t ratchet_index;
size_t length = check_error(
olm_inbound_group_session_last_error,
session,
"Error decrypting message",
olm_group_decrypt(
session,
message_buffer, message_length,
plaintext, max_length, &ratchet_index
)
);
(void)write(STDOUT_FILENO, plaintext, length);
(void)write(STDOUT_FILENO, "\n", 1);
}
free(session_buffer);
free(message_buffer);
free(tmp_buffer);
return EXIT_SUCCESS;
}

View file

@ -1,41 +0,0 @@
#include "fuzzing.hh"
#include "olm/account.hh"
#include "olm/olm.h"
size_t fuzz_unpickle_account(
OlmAccount * account, void * pickled, size_t pickled_length
) {
olm::Account & object = *reinterpret_cast<olm::Account *>(account);
std::uint8_t * const pos = reinterpret_cast<std::uint8_t *>(pickled);
std::uint8_t * const end = pos + pickled_length;
if (!unpickle(pos, end, object)) {
if (object.last_error == OlmErrorCode::OLM_SUCCESS) {
object.last_error = OlmErrorCode::OLM_CORRUPTED_PICKLE;
}
return std::size_t(-1);
}
return pickled_length;
}
int main(int argc, const char * argv[]) {
int pickle_fd = STDIN_FILENO;
uint8_t * pickle_buffer;
ssize_t pickle_length = check_errno(
"Error reading pickle file", read_file(pickle_fd, &pickle_buffer));
void * account_buf = malloc(olm_account_size());
if (!account_buf) {
return 3;
}
OlmAccount * account = olm_account(account_buf);
check_error(olm_account_last_error, account, "Error unpickling account",
fuzz_unpickle_account(account, pickle_buffer, pickle_length));
free(pickle_buffer);
free(account);
return EXIT_SUCCESS;
}

View file

@ -1,28 +0,0 @@
#include <olm/outbound_group_session.h>
#include "fuzzing.h"
int main(int argc, const char *argv[]) {
if (argc != 1) {
printf("Usage: %s <input_file\n", argv[0]);
exit(3);
}
void *session_buffer = malloc(olm_outbound_group_session_size());
OlmOutboundGroupSession *session = olm_outbound_group_session(session_buffer);
int pickle_fd = STDIN_FILENO;
uint8_t *pickle_buffer;
ssize_t pickle_length = check_errno("Error reading message file",
read_file(pickle_fd, &pickle_buffer));
check_outbound_group_session(
session, "Error unpickling outbound group session",
olm_unpickle_outbound_group_session(session, "", 0, pickle_buffer,
pickle_length));
free(session_buffer);
free(pickle_buffer);
return EXIT_SUCCESS;
}

View file

@ -1,101 +0,0 @@
#include "olm/olm.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stddef.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define OLM_FUZZING 1
ssize_t read_file(
int fd,
uint8_t **buffer
) {
size_t buffer_size = 1;
size_t buffer_pos = 0;
uint8_t * current_buffer = (uint8_t *) malloc(buffer_size);
if (!current_buffer) return -1;
while (1) {
ssize_t count = read(
fd, current_buffer + buffer_pos, buffer_size - buffer_pos
);
if (count < 0) break; // A read error happened, so just fail immediately.
if (count == 0) {
// Nothing more left to read. We downsize the buffer to fit the
// data exactly, unless no data was read at all, in which case we
// skip the downsizing.
if (buffer_pos != 0) {
current_buffer = (uint8_t *) realloc(current_buffer, buffer_pos);
if (!current_buffer) break;
}
// The read was successful so we return the allocated buffer.
*buffer = current_buffer;
return buffer_pos;
}
buffer_pos += count;
// We've reached capacity, so enlarge the buffer.
if (buffer_pos == buffer_size) {
buffer_size *= 2;
uint8_t * new_buffer = (uint8_t *) realloc(current_buffer, buffer_size);
if (!new_buffer) break;
current_buffer = new_buffer;
}
}
free(current_buffer);
return -1;
}
ssize_t check_errno(
const char * message,
ssize_t value
) {
if (value == (ssize_t)-1) {
perror(message);
exit(1);
}
return value;
}
size_t check_error(
const char * message,
const char * olm_message,
size_t value
) {
if (value == olm_error()) {
(void)write(STDERR_FILENO, message, strlen(message));
(void)write(STDERR_FILENO, ": ", 2);
(void)write(STDERR_FILENO, olm_message, strlen(olm_message));
(void)write(STDERR_FILENO, "\n", 1);
exit(2);
}
return value;
}
size_t check_session(
OlmSession * session,
const char * message,
size_t value
) {
return check_error(message, olm_session_last_error(session), value);
}
size_t check_outbound_group_session(
OlmOutboundGroupSession * session,
const char * message,
size_t value
) {
return check_error(message, olm_outbound_group_session_last_error(session), value);
}

View file

@ -1,118 +0,0 @@
#!/usr/bin/bash
# Needs to be started in tmux.
script_dir() {
dirname "$(readlink -f "$0")"
}
fuzzer_dir() {
printf '%s/fuzzers\n' "$(script_dir)"
}
fuzzer_list() {
find "$(fuzzer_dir)" -maxdepth 1 -type f \( -name '*.cpp' -or -name '*.c' \) -printf '%P\n' \
| while read -r fuzzer; do
fuzzer="${fuzzer#fuzz_}"
printf '%s\n' "${fuzzer%.c*}"
done
}
usage() {
printf '%s: HARNESS FUZZER\n\n' "$(basename "$0")"
printf ' HARNESS ∈ {\n'
# We want word-splitting here so that each fuzzer ends up as a separate
# argument.
# shellcheck disable=SC2046
printf '%30s,\n' $(fuzzer_list | tr '\n' ' ')
printf ' }\n'
printf ' FUZZER ∈ {afl, afl++}\n'
}
if [[ $# -ne 2 ]]; then
usage
exit 1
fi
case "$2" in
afl++)
export AFL_PATH=/home/dkasak/code/projects/afl/afl++
export AFL_AUTORESUME=1
AFL_ARGS_FUZZER0="-D"
AFL_ARGS_FUZZER1="-L 0"
AFL_ARGS_FUZZER2="-p rare"
AFL_ARGS_FUZZER3="-p fast"
AFL_ARGS_FUZZER4="-p exploit"
AFL_ARGS_FUZZER5="-p explore"
;;
afl)
export AFL_PATH=/usr/bin
;;
*)
printf 'Unknown fuzzer: %s\n' "$2"
exit 1
;;
esac
export AFL=$AFL_PATH/afl-fuzz
export AFL_TMPDIR=/tmp
case "$1" in
group_decrypt)
FUZZER_ARG1="fuzzing/$1/pickled-inbound-group-session.txt"
;;
decrypt)
FUZZER_ARG1="fuzzing/$1/pickled-session.txt"
FUZZER_ARG2="1"
;;
decode_message)
;;
unpickle_session)
;;
unpickle_account)
;;
unpickle_account_test)
;;
unpickle_megolm_outbound)
;;
*)
printf 'Unknown harness: %s\n' "$1"
exit 1
;;
esac
cd "$(script_dir)" || exit 1
# Fuzzer args are deliberately not quoted below so that word-splitting happens.
# This is used so that they expand into nothing in cases where they are missing
# or to expand into multiple arguments from a string definition.
# shellcheck disable=SC2086
tmux new-window -d -n "M" -- \
"$AFL" -i "corpora/$1/in" -o "corpora/$1/out" -M i0 "$AFL_ARGS_FUZZER0" \
-- "../build/fuzzers/fuzz_$1" $FUZZER_ARG1 $FUZZER_ARG2
# shellcheck disable=SC2086
tmux new-window -d -n "S1" -- \
"$AFL" -i "corpora/$1/in" -o "corpora/$1/out" -S i1 "$AFL_ARGS_FUZZER1" \
-- "../build/fuzzers/fuzz_$1" $FUZZER_ARG1 $FUZZER_ARG2
# shellcheck disable=SC2086
tmux new-window -d -n "S2" -- \
"$AFL" -i "corpora/$1/in" -o "corpora/$1/out" -S i2 $AFL_ARGS_FUZZER2 \
-- "../build/fuzzers/fuzz_$1" $FUZZER_ARG1 $FUZZER_ARG2
# shellcheck disable=SC2086
tmux new-window -d -n "S3" -- \
"$AFL" -i "corpora/$1/in" -o "corpora/$1/out" -S i3 $AFL_ARGS_FUZZER3 \
-- "../build/fuzzers/fuzz_$1" $FUZZER_ARG1 $FUZZER_ARG2
# shellcheck disable=SC2086
tmux new-window -d -n "S4" -- \
"$AFL" -i "corpora/$1/in" -o "corpora/$1/out" -S i4 $AFL_ARGS_FUZZER4 \
-- "../build/fuzzers/fuzz_$1_asan" $FUZZER_ARG1 $FUZZER_ARG2
# shellcheck disable=SC2086
tmux new-window -d -n "S5" -- \
"$AFL" -i "corpora/$1/in" -o "corpora/$1/out" -S i5 $AFL_ARGS_FUZZER5 \
-- "../build/fuzzers/fuzz_$1" $FUZZER_ARG1 $FUZZER_ARG2

View file

@ -1,17 +0,0 @@
function Math(el)
if el.mathtype == "InlineMath" then
if el.text:sub(1,1) == '`' and el.text:sub(#el.text) == '`' then
local text = el.text:sub(2,#el.text-1)
return pandoc.Math(el.mathtype, text)
else
local cont = pandoc.read(el.text)
return { pandoc.Str("$") } .. cont.blocks[1].content .. { pandoc.Str("$") }
end
end
end
function CodeBlock(el)
if el.classes[1] == "math" then
return pandoc.Para({ pandoc.Math("DisplayMath", el.text) })
end
end

View file

@ -1,4 +0,0 @@
module libolm {
header "olm/olm.h"
export *
}

View file

@ -43,14 +43,11 @@ struct Account {
Account(); Account();
IdentityKeys identity_keys; IdentityKeys identity_keys;
List<OneTimeKey, MAX_ONE_TIME_KEYS> one_time_keys; List<OneTimeKey, MAX_ONE_TIME_KEYS> one_time_keys;
std::uint8_t num_fallback_keys;
OneTimeKey current_fallback_key;
OneTimeKey prev_fallback_key;
std::uint32_t next_one_time_key_id; std::uint32_t next_one_time_key_id;
OlmErrorCode last_error; OlmErrorCode last_error;
/** Number of random bytes needed to create a new account */ /** Number of random bytes needed to create a new account */
std::size_t new_account_random_length() const; std::size_t new_account_random_length();
/** Create a new account. Returns std::size_t(-1) on error. If the number of /** Create a new account. Returns std::size_t(-1) on error. If the number of
* random bytes is too small then last_error will be NOT_ENOUGH_RANDOM */ * random bytes is too small then last_error will be NOT_ENOUGH_RANDOM */
@ -59,7 +56,7 @@ struct Account {
); );
/** Number of bytes needed to output the identity keys for this account */ /** Number of bytes needed to output the identity keys for this account */
std::size_t get_identity_json_length() const; std::size_t get_identity_json_length();
/** Output the identity keys for this account as JSON in the following /** Output the identity keys for this account as JSON in the following
* format: * format:
@ -78,7 +75,7 @@ struct Account {
/** /**
* The length of an ed25519 signature in bytes. * The length of an ed25519 signature in bytes.
*/ */
std::size_t signature_length() const; std::size_t signature_length();
/** /**
* Signs a message with the ed25519 key for this account. * Signs a message with the ed25519 key for this account.
@ -89,7 +86,7 @@ struct Account {
); );
/** Number of bytes needed to output the one time keys for this account */ /** Number of bytes needed to output the one time keys for this account */
std::size_t get_one_time_keys_json_length() const; std::size_t get_one_time_keys_json_length();
/** Output the one time keys that haven't been published yet as JSON: /** Output the one time keys that haven't been published yet as JSON:
* *
@ -107,20 +104,18 @@ struct Account {
std::uint8_t * one_time_json, std::size_t one_time_json_length std::uint8_t * one_time_json, std::size_t one_time_json_length
); );
/** Mark the current list of one_time_keys and the current fallback key as /** Mark the current list of one_time_keys as being published. They
* being published. The current one time keys will no longer be returned by * will no longer be returned by get_one_time_keys_json_length(). */
* get_one_time_keys_json() and the current fallback key will no longer be
* returned by get_unpublished_fallback_key_json(). */
std::size_t mark_keys_as_published(); std::size_t mark_keys_as_published();
/** The largest number of one time keys this account can store. */ /** The largest number of one time keys this account can store. */
std::size_t max_number_of_one_time_keys() const; std::size_t max_number_of_one_time_keys();
/** The number of random bytes needed to generate a given number of new one /** The number of random bytes needed to generate a given number of new one
* time keys. */ * time keys. */
std::size_t generate_one_time_keys_random_length( std::size_t generate_one_time_keys_random_length(
std::size_t number_of_keys std::size_t number_of_keys
) const; );
/** Generates a number of new one time keys. If the total 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 * stored by this account exceeds max_number_of_one_time_keys() then the
@ -131,49 +126,6 @@ struct Account {
std::uint8_t const * random, std::size_t random_length std::uint8_t const * random, std::size_t random_length
); );
/** The number of random bytes needed to generate a fallback key. */
std::size_t generate_fallback_key_random_length() const;
/** Generates a new fallback key. Returns std::size_t(-1) on error. If the
* number of random bytes is too small then last_error will be
* NOT_ENOUGH_RANDOM */
std::size_t generate_fallback_key(
std::uint8_t const * random, std::size_t random_length
);
/** Number of bytes needed to output the fallback keys for this account */
std::size_t get_fallback_key_json_length() const;
/** Deprecated: use get_unpublished_fallback_key_json instead */
std::size_t get_fallback_key_json(
std::uint8_t * fallback_json, std::size_t fallback_json_length
);
/** Number of bytes needed to output the unpublished fallback keys for this
* account */
std::size_t get_unpublished_fallback_key_json_length() const;
/** Output the fallback key as JSON:
*
* {"curve25519":
* ["<6 byte key id>":"<43 base64 characters>"
* ,"<6 byte key id>":"<43 base64 characters>"
* ...
* ]
* }
*
* if there is a fallback key and it has not been published yet.
*
* Returns the size of the JSON written or std::size_t(-1) on error.
* If the buffer is too small last_error will be OUTPUT_BUFFER_TOO_SMALL.
*/
std::size_t get_unpublished_fallback_key_json(
std::uint8_t * fallback_json, std::size_t fallback_json_length
);
/** Forget about the old fallback key */
void forget_old_fallback_key();
/** Lookup a one time key with the given public key */ /** Lookup a one time key with the given public key */
OneTimeKey const * lookup_key( OneTimeKey const * lookup_key(
_olm_curve25519_public_key const & public_key _olm_curve25519_public_key const & public_key

View file

@ -22,10 +22,6 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
// Note: exports in this file are only for unit tests. Nobody else should be
// using this externally
#include "olm/olm_export.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -34,7 +30,7 @@ extern "C" {
/** /**
* The number of bytes of unpadded base64 needed to encode a length of input. * The number of bytes of unpadded base64 needed to encode a length of input.
*/ */
OLM_EXPORT size_t _olm_encode_base64_length( size_t _olm_encode_base64_length(
size_t input_length size_t input_length
); );
@ -46,7 +42,7 @@ OLM_EXPORT size_t _olm_encode_base64_length(
* *
* Returns number of bytes encoded * Returns number of bytes encoded
*/ */
OLM_EXPORT size_t _olm_encode_base64( size_t _olm_encode_base64(
uint8_t const * input, size_t input_length, uint8_t const * input, size_t input_length,
uint8_t * output uint8_t * output
); );
@ -55,7 +51,7 @@ OLM_EXPORT size_t _olm_encode_base64(
* The number of bytes of raw data a length of unpadded base64 will encode to. * 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. * Returns size_t(-1) if the length is not a valid length for base64.
*/ */
OLM_EXPORT size_t _olm_decode_base64_length( size_t _olm_decode_base64_length(
size_t input_length size_t input_length
); );
@ -67,7 +63,7 @@ OLM_EXPORT size_t _olm_decode_base64_length(
* *
* Returns number of bytes decoded * Returns number of bytes decoded
*/ */
OLM_EXPORT size_t _olm_decode_base64( size_t _olm_decode_base64(
uint8_t const * input, size_t input_length, uint8_t const * input, size_t input_length,
uint8_t * output uint8_t * output
); );

View file

@ -18,16 +18,12 @@
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
// Note: exports in this file are only for unit tests. Nobody else should be
// using this externally
#include "olm/olm_export.h"
namespace olm { namespace olm {
/** /**
* The number of bytes of unpadded base64 needed to encode a length of input. * The number of bytes of unpadded base64 needed to encode a length of input.
*/ */
OLM_EXPORT std::size_t encode_base64_length( std::size_t encode_base64_length(
std::size_t input_length std::size_t input_length
); );
@ -37,7 +33,7 @@ OLM_EXPORT std::size_t encode_base64_length(
* The input can overlap with the last three quarters of 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. * That is, the input pointer may be output + output_length - input_length.
*/ */
OLM_EXPORT std::uint8_t * encode_base64( std::uint8_t * encode_base64(
std::uint8_t const * input, std::size_t input_length, std::uint8_t const * input, std::size_t input_length,
std::uint8_t * output std::uint8_t * output
); );
@ -46,7 +42,7 @@ OLM_EXPORT std::uint8_t * encode_base64(
* The number of bytes of raw data a length of unpadded base64 will encode to. * The number of bytes of raw data a length of unpadded base64 will encode to.
* Returns std::size_t(-1) if the length is not a valid length for base64. * Returns std::size_t(-1) if the length is not a valid length for base64.
*/ */
OLM_EXPORT std::size_t decode_base64_length( std::size_t decode_base64_length(
std::size_t input_length std::size_t input_length
); );
@ -55,12 +51,8 @@ OLM_EXPORT std::size_t decode_base64_length(
* Writes decode_base64_length(input_length) bytes to the output buffer. * Writes decode_base64_length(input_length) bytes to the output buffer.
* The output can overlap with the first three quarters of the input 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. * That is, the input pointers and output pointer may be the same.
*
* Returns the number of bytes of raw data the base64 input decoded to. If the
* input length supplied is not a valid length for base64, returns
* std::size_t(-1) and does not decode.
*/ */
OLM_EXPORT std::size_t decode_base64( std::uint8_t const * decode_base64(
std::uint8_t const * input, std::size_t input_length, std::uint8_t const * input, std::size_t input_length,
std::uint8_t * output std::uint8_t * output
); );

View file

@ -19,10 +19,6 @@
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
// Note: exports in this file are only for unit tests. Nobody else should be
// using this externally
#include "olm/olm_export.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -115,7 +111,7 @@ struct _olm_cipher_aes_sha_256 {
size_t kdf_info_length; size_t kdf_info_length;
}; };
OLM_EXPORT extern const struct _olm_cipher_ops _olm_cipher_aes_sha_256_ops; 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. * get an initializer for an instance of struct _olm_cipher_aes_sha_256.

View file

@ -20,10 +20,6 @@
#ifndef OLM_CRYPTO_H_ #ifndef OLM_CRYPTO_H_
#define OLM_CRYPTO_H_ #define OLM_CRYPTO_H_
// Note: exports in this file are only for unit tests. Nobody else should be
// using this externally
#include "olm/olm_export.h"
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
@ -98,13 +94,13 @@ struct _olm_ed25519_key_pair {
/** The length of output the aes_encrypt_cbc function will write */ /** The length of output the aes_encrypt_cbc function will write */
OLM_EXPORT size_t _olm_crypto_aes_encrypt_cbc_length( size_t _olm_crypto_aes_encrypt_cbc_length(
size_t input_length size_t input_length
); );
/** Encrypts the input using AES256 in CBC mode with PKCS#7 padding. /** Encrypts the input using AES256 in CBC mode with PKCS#7 padding.
* The output buffer must be big enough to hold the output including padding */ * The output buffer must be big enough to hold the output including padding */
OLM_EXPORT void _olm_crypto_aes_encrypt_cbc( void _olm_crypto_aes_encrypt_cbc(
const struct _olm_aes256_key *key, const struct _olm_aes256_key *key,
const struct _olm_aes256_iv *iv, const struct _olm_aes256_iv *iv,
const uint8_t *input, size_t input_length, const uint8_t *input, size_t input_length,
@ -115,7 +111,7 @@ OLM_EXPORT void _olm_crypto_aes_encrypt_cbc(
* least the same size as the input buffer. Returns the length of the plaintext * least the same size as the input buffer. Returns the length of the plaintext
* without padding on success or std::size_t(-1) if the padding is invalid. * without padding on success or std::size_t(-1) if the padding is invalid.
*/ */
OLM_EXPORT size_t _olm_crypto_aes_decrypt_cbc( size_t _olm_crypto_aes_decrypt_cbc(
const struct _olm_aes256_key *key, const struct _olm_aes256_key *key,
const struct _olm_aes256_iv *iv, const struct _olm_aes256_iv *iv,
uint8_t const * input, size_t input_length, uint8_t const * input, size_t input_length,
@ -125,7 +121,7 @@ OLM_EXPORT size_t _olm_crypto_aes_decrypt_cbc(
/** Computes SHA-256 of the input. The output buffer must be a least /** Computes SHA-256 of the input. The output buffer must be a least
* SHA256_OUTPUT_LENGTH (32) bytes long. */ * SHA256_OUTPUT_LENGTH (32) bytes long. */
OLM_EXPORT void _olm_crypto_sha256( void _olm_crypto_sha256(
uint8_t const * input, size_t input_length, uint8_t const * input, size_t input_length,
uint8_t * output uint8_t * output
); );
@ -134,7 +130,7 @@ OLM_EXPORT void _olm_crypto_sha256(
* http://tools.ietf.org/html/rfc2104 * http://tools.ietf.org/html/rfc2104
* Computes HMAC-SHA-256 of the input for the key. The output buffer must * Computes HMAC-SHA-256 of the input for the key. The output buffer must
* be at least SHA256_OUTPUT_LENGTH (32) bytes long. */ * be at least SHA256_OUTPUT_LENGTH (32) bytes long. */
OLM_EXPORT void _olm_crypto_hmac_sha256( void _olm_crypto_hmac_sha256(
uint8_t const * key, size_t key_length, uint8_t const * key, size_t key_length,
uint8_t const * input, size_t input_length, uint8_t const * input, size_t input_length,
uint8_t * output uint8_t * output
@ -144,7 +140,7 @@ OLM_EXPORT void _olm_crypto_hmac_sha256(
/** HMAC-based Key Derivation Function (HKDF) /** HMAC-based Key Derivation Function (HKDF)
* https://tools.ietf.org/html/rfc5869 * https://tools.ietf.org/html/rfc5869
* Derives key material from the input bytes. */ * Derives key material from the input bytes. */
OLM_EXPORT void _olm_crypto_hkdf_sha256( void _olm_crypto_hkdf_sha256(
uint8_t const * input, size_t input_length, uint8_t const * input, size_t input_length,
uint8_t const * info, size_t info_length, uint8_t const * info, size_t info_length,
uint8_t const * salt, size_t salt_length, uint8_t const * salt, size_t salt_length,
@ -155,7 +151,7 @@ OLM_EXPORT void _olm_crypto_hkdf_sha256(
/** Generate a curve25519 key pair /** Generate a curve25519 key pair
* random_32_bytes should be CURVE25519_RANDOM_LENGTH (32) bytes long. * random_32_bytes should be CURVE25519_RANDOM_LENGTH (32) bytes long.
*/ */
OLM_EXPORT void _olm_crypto_curve25519_generate_key( void _olm_crypto_curve25519_generate_key(
uint8_t const * random_32_bytes, uint8_t const * random_32_bytes,
struct _olm_curve25519_key_pair *output struct _olm_curve25519_key_pair *output
); );
@ -164,7 +160,7 @@ OLM_EXPORT void _olm_crypto_curve25519_generate_key(
/** Create a shared secret using our private key and their public key. /** Create a shared secret using our private key and their public key.
* The output buffer must be at least CURVE25519_SHARED_SECRET_LENGTH (32) bytes long. * The output buffer must be at least CURVE25519_SHARED_SECRET_LENGTH (32) bytes long.
*/ */
OLM_EXPORT void _olm_crypto_curve25519_shared_secret( void _olm_crypto_curve25519_shared_secret(
const struct _olm_curve25519_key_pair *our_key, const struct _olm_curve25519_key_pair *our_key,
const struct _olm_curve25519_public_key *their_key, const struct _olm_curve25519_public_key *their_key,
uint8_t * output uint8_t * output
@ -173,7 +169,7 @@ OLM_EXPORT void _olm_crypto_curve25519_shared_secret(
/** Generate an ed25519 key pair /** Generate an ed25519 key pair
* random_32_bytes should be ED25519_RANDOM_LENGTH (32) bytes long. * random_32_bytes should be ED25519_RANDOM_LENGTH (32) bytes long.
*/ */
OLM_EXPORT void _olm_crypto_ed25519_generate_key( void _olm_crypto_ed25519_generate_key(
uint8_t const * random_bytes, uint8_t const * random_bytes,
struct _olm_ed25519_key_pair *output struct _olm_ed25519_key_pair *output
); );
@ -182,7 +178,7 @@ OLM_EXPORT void _olm_crypto_ed25519_generate_key(
* *
* The output buffer must be at least ED25519_SIGNATURE_LENGTH (64) bytes * The output buffer must be at least ED25519_SIGNATURE_LENGTH (64) bytes
* long. */ * long. */
OLM_EXPORT void _olm_crypto_ed25519_sign( void _olm_crypto_ed25519_sign(
const struct _olm_ed25519_key_pair *our_key, const struct _olm_ed25519_key_pair *our_key,
const uint8_t * message, size_t message_length, const uint8_t * message, size_t message_length,
uint8_t * output uint8_t * output
@ -191,7 +187,7 @@ OLM_EXPORT void _olm_crypto_ed25519_sign(
/** Verify an ed25519 signature /** Verify an ed25519 signature
* The signature input buffer must be ED25519_SIGNATURE_LENGTH (64) bytes long. * The signature input buffer must be ED25519_SIGNATURE_LENGTH (64) bytes long.
* Returns non-zero if the signature is valid. */ * Returns non-zero if the signature is valid. */
OLM_EXPORT int _olm_crypto_ed25519_verify( int _olm_crypto_ed25519_verify(
const struct _olm_ed25519_public_key *their_key, const struct _olm_ed25519_public_key *their_key,
const uint8_t * message, size_t message_length, const uint8_t * message, size_t message_length,
const uint8_t * signature const uint8_t * signature

View file

@ -15,8 +15,6 @@
#ifndef OLM_ERROR_H_ #ifndef OLM_ERROR_H_
#define OLM_ERROR_H_ #define OLM_ERROR_H_
#include "olm/olm_export.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -55,23 +53,17 @@ enum OlmErrorCode {
OLM_INPUT_BUFFER_TOO_SMALL = 15, OLM_INPUT_BUFFER_TOO_SMALL = 15,
/** // Not an error code, just here to pad out the enum past 16 because
* SAS doesn't have their key set. // otherwise the compiler warns about a redunant check. If you're
*/ // adding an error code, replace this one!
OLM_SAS_THEIR_KEY_NOT_SET = 16, OLM_ERROR_NOT_INVENTED_YET = 16,
/**
* The pickled object was successfully decoded, but the unpickling still failed
* because it had some extraneous junk data at the end.
*/
OLM_PICKLE_EXTRA_DATA = 17,
/* remember to update the list of string constants in error.c when updating /* remember to update the list of string constants in error.c when updating
* this list. */ * this list. */
}; };
/** get a string representation of the given error code. */ /** get a string representation of the given error code. */
OLM_EXPORT const char * _olm_error_to_string(enum OlmErrorCode error); const char * _olm_error_to_string(enum OlmErrorCode error);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"

View file

@ -18,10 +18,6 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "olm/error.h"
#include "olm/olm_export.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -29,38 +25,31 @@ extern "C" {
typedef struct OlmInboundGroupSession OlmInboundGroupSession; typedef struct OlmInboundGroupSession OlmInboundGroupSession;
/** get the size of an inbound group session, in bytes. */ /** get the size of an inbound group session, in bytes. */
OLM_EXPORT size_t olm_inbound_group_session_size(void); size_t olm_inbound_group_session_size(void);
/** /**
* Initialise an inbound group session object using the supplied memory * Initialise an inbound group session object using the supplied memory
* The supplied memory should be at least olm_inbound_group_session_size() * The supplied memory should be at least olm_inbound_group_session_size()
* bytes. * bytes.
*/ */
OLM_EXPORT OlmInboundGroupSession * olm_inbound_group_session( OlmInboundGroupSession * olm_inbound_group_session(
void *memory void *memory
); );
/** /**
* A null terminated string describing the most recent error to happen to a * A null terminated string describing the most recent error to happen to a
* group session */ * group session */
OLM_EXPORT const char *olm_inbound_group_session_last_error( const char *olm_inbound_group_session_last_error(
const OlmInboundGroupSession *session
);
/**
* An error code describing the most recent error to happen to a group
* session */
OLM_EXPORT enum OlmErrorCode olm_inbound_group_session_last_error_code(
const OlmInboundGroupSession *session const OlmInboundGroupSession *session
); );
/** Clears the memory used to back this group session */ /** Clears the memory used to back this group session */
OLM_EXPORT size_t olm_clear_inbound_group_session( size_t olm_clear_inbound_group_session(
OlmInboundGroupSession *session OlmInboundGroupSession *session
); );
/** Returns the number of bytes needed to store an inbound group session */ /** Returns the number of bytes needed to store an inbound group session */
OLM_EXPORT size_t olm_pickle_inbound_group_session_length( size_t olm_pickle_inbound_group_session_length(
const OlmInboundGroupSession *session const OlmInboundGroupSession *session
); );
@ -72,7 +61,7 @@ OLM_EXPORT size_t olm_pickle_inbound_group_session_length(
* is smaller than olm_pickle_inbound_group_session_length() then * is smaller than olm_pickle_inbound_group_session_length() then
* olm_inbound_group_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" * olm_inbound_group_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL"
*/ */
OLM_EXPORT size_t olm_pickle_inbound_group_session( size_t olm_pickle_inbound_group_session(
OlmInboundGroupSession *session, OlmInboundGroupSession *session,
void const * key, size_t key_length, void const * key, size_t key_length,
void * pickled, size_t pickled_length void * pickled, size_t pickled_length
@ -88,7 +77,7 @@ OLM_EXPORT size_t olm_pickle_inbound_group_session(
* olm_inbound_group_session_last_error() will be "INVALID_BASE64". The input * olm_inbound_group_session_last_error() will be "INVALID_BASE64". The input
* pickled buffer is destroyed * pickled buffer is destroyed
*/ */
OLM_EXPORT size_t olm_unpickle_inbound_group_session( size_t olm_unpickle_inbound_group_session(
OlmInboundGroupSession *session, OlmInboundGroupSession *session,
void const * key, size_t key_length, void const * key, size_t key_length,
void * pickled, size_t pickled_length void * pickled, size_t pickled_length
@ -105,7 +94,7 @@ OLM_EXPORT size_t olm_unpickle_inbound_group_session(
* * OLM_INVALID_BASE64 if the session_key is not valid base64 * * OLM_INVALID_BASE64 if the session_key is not valid base64
* * OLM_BAD_SESSION_KEY if the session_key is invalid * * OLM_BAD_SESSION_KEY if the session_key is invalid
*/ */
OLM_EXPORT size_t olm_init_inbound_group_session( size_t olm_init_inbound_group_session(
OlmInboundGroupSession *session, OlmInboundGroupSession *session,
/* base64-encoded keys */ /* base64-encoded keys */
uint8_t const * session_key, size_t session_key_length uint8_t const * session_key, size_t session_key_length
@ -120,7 +109,7 @@ OLM_EXPORT size_t olm_init_inbound_group_session(
* * OLM_INVALID_BASE64 if the session_key is not valid base64 * * OLM_INVALID_BASE64 if the session_key is not valid base64
* * OLM_BAD_SESSION_KEY if the session_key is invalid * * OLM_BAD_SESSION_KEY if the session_key is invalid
*/ */
OLM_EXPORT size_t olm_import_inbound_group_session( size_t olm_import_inbound_group_session(
OlmInboundGroupSession *session, OlmInboundGroupSession *session,
/* base64-encoded keys; note that it will be overwritten with the base64-decoded /* base64-encoded keys; note that it will be overwritten with the base64-decoded
data. */ data. */
@ -137,7 +126,7 @@ OLM_EXPORT size_t olm_import_inbound_group_session(
* *
* Returns olm_error() on failure. * Returns olm_error() on failure.
*/ */
OLM_EXPORT size_t olm_group_decrypt_max_plaintext_length( size_t olm_group_decrypt_max_plaintext_length(
OlmInboundGroupSession *session, OlmInboundGroupSession *session,
uint8_t * message, size_t message_length uint8_t * message, size_t message_length
); );
@ -161,7 +150,7 @@ OLM_EXPORT size_t olm_group_decrypt_max_plaintext_length(
* message's index (ie, it was sent before the session key was shared with * message's index (ie, it was sent before the session key was shared with
* us) * us)
*/ */
OLM_EXPORT size_t olm_group_decrypt( size_t olm_group_decrypt(
OlmInboundGroupSession *session, OlmInboundGroupSession *session,
/* input; note that it will be overwritten with the base64-decoded /* input; note that it will be overwritten with the base64-decoded
@ -177,7 +166,7 @@ OLM_EXPORT size_t olm_group_decrypt(
/** /**
* Get the number of bytes returned by olm_inbound_group_session_id() * Get the number of bytes returned by olm_inbound_group_session_id()
*/ */
OLM_EXPORT size_t olm_inbound_group_session_id_length( size_t olm_inbound_group_session_id_length(
const OlmInboundGroupSession *session const OlmInboundGroupSession *session
); );
@ -189,7 +178,7 @@ OLM_EXPORT size_t olm_inbound_group_session_id_length(
* last_error will be OUTPUT_BUFFER_TOO_SMALL if the id buffer was too * last_error will be OUTPUT_BUFFER_TOO_SMALL if the id buffer was too
* small. * small.
*/ */
OLM_EXPORT size_t olm_inbound_group_session_id( size_t olm_inbound_group_session_id(
OlmInboundGroupSession *session, OlmInboundGroupSession *session,
uint8_t * id, size_t id_length uint8_t * id, size_t id_length
); );
@ -197,7 +186,7 @@ OLM_EXPORT size_t olm_inbound_group_session_id(
/** /**
* Get the first message index we know how to decrypt. * Get the first message index we know how to decrypt.
*/ */
OLM_EXPORT uint32_t olm_inbound_group_session_first_known_index( uint32_t olm_inbound_group_session_first_known_index(
const OlmInboundGroupSession *session const OlmInboundGroupSession *session
); );
@ -210,14 +199,14 @@ OLM_EXPORT uint32_t olm_inbound_group_session_first_known_index(
* *
* This is mainly intended for the unit tests, currently. * This is mainly intended for the unit tests, currently.
*/ */
OLM_EXPORT int olm_inbound_group_session_is_verified( int olm_inbound_group_session_is_verified(
const OlmInboundGroupSession *session const OlmInboundGroupSession *session
); );
/** /**
* Get the number of bytes returned by olm_export_inbound_group_session() * Get the number of bytes returned by olm_export_inbound_group_session()
*/ */
OLM_EXPORT size_t olm_export_inbound_group_session_length( size_t olm_export_inbound_group_session_length(
const OlmInboundGroupSession *session const OlmInboundGroupSession *session
); );
@ -233,7 +222,7 @@ OLM_EXPORT size_t olm_export_inbound_group_session_length(
* given index (ie, it was sent before the session key was shared with * given index (ie, it was sent before the session key was shared with
* us) * us)
*/ */
OLM_EXPORT size_t olm_export_inbound_group_session( size_t olm_export_inbound_group_session(
OlmInboundGroupSession *session, OlmInboundGroupSession *session,
uint8_t * key, size_t key_length, uint32_t message_index uint8_t * key, size_t key_length, uint32_t message_index
); );

View file

@ -99,9 +99,9 @@ public:
return *this; return *this;
} }
T * this_pos = _data; T * this_pos = _data;
const T * other_pos = other._data; T * const other_pos = other._data;
while (other_pos != other._end) { while (other_pos != other._end) {
*this_pos = *other_pos; *this_pos = *other;
++this_pos; ++this_pos;
++other_pos; ++other_pos;
} }

View file

@ -23,10 +23,6 @@
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
// Note: exports in this file are only for unit tests. Nobody else should be
// using this externally
#include "olm/olm_export.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -63,25 +59,25 @@ extern const struct _olm_cipher *megolm_cipher;
* initialize the megolm ratchet. random_data should be at least * initialize the megolm ratchet. random_data should be at least
* MEGOLM_RATCHET_LENGTH bytes of randomness. * MEGOLM_RATCHET_LENGTH bytes of randomness.
*/ */
OLM_EXPORT void megolm_init(Megolm *megolm, uint8_t const *random_data, uint32_t counter); void megolm_init(Megolm *megolm, uint8_t const *random_data, uint32_t counter);
/** Returns the number of bytes needed to store a megolm */ /** Returns the number of bytes needed to store a megolm */
OLM_EXPORT size_t megolm_pickle_length(const Megolm *megolm); size_t megolm_pickle_length(const Megolm *megolm);
/** /**
* Pickle the megolm. Returns a pointer to the next free space in the buffer. * Pickle the megolm. Returns a pointer to the next free space in the buffer.
*/ */
OLM_EXPORT uint8_t * megolm_pickle(const Megolm *megolm, uint8_t *pos); uint8_t * megolm_pickle(const Megolm *megolm, uint8_t *pos);
/** /**
* Unpickle the megolm. Returns a pointer to the next item in the buffer. * Unpickle the megolm. Returns a pointer to the next item in the buffer.
*/ */
OLM_EXPORT const uint8_t * megolm_unpickle(Megolm *megolm, const uint8_t *pos, const uint8_t * megolm_unpickle(Megolm *megolm, const uint8_t *pos,
const uint8_t *end); const uint8_t *end);
/** advance the ratchet by one step */ /** advance the ratchet by one step */
OLM_EXPORT void megolm_advance(Megolm *megolm); void megolm_advance(Megolm *megolm);
/** /**
* get the key data in the ratchet. The returned data is * get the key data in the ratchet. The returned data is
@ -90,7 +86,7 @@ OLM_EXPORT void megolm_advance(Megolm *megolm);
#define megolm_get_data(megolm) ((const uint8_t *)((megolm)->data)) #define megolm_get_data(megolm) ((const uint8_t *)((megolm)->data))
/** advance the ratchet to a given count */ /** advance the ratchet to a given count */
OLM_EXPORT void megolm_advance_to(Megolm *megolm, uint32_t advance_to); void megolm_advance_to(Megolm *megolm, uint32_t advance_to);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"

View file

@ -27,10 +27,6 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
// Note: exports in this file are only for unit tests. Nobody else should be
// using this externally
#include "olm/olm_export.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -38,7 +34,7 @@ extern "C" {
/** /**
* The length of the buffer needed to hold a group message. * The length of the buffer needed to hold a group message.
*/ */
OLM_EXPORT size_t _olm_encode_group_message_length( size_t _olm_encode_group_message_length(
uint32_t chain_index, uint32_t chain_index,
size_t ciphertext_length, size_t ciphertext_length,
size_t mac_length, size_t mac_length,
@ -59,7 +55,7 @@ OLM_EXPORT size_t _olm_encode_group_message_length(
* *
* Returns the size of the message, up to the MAC. * Returns the size of the message, up to the MAC.
*/ */
OLM_EXPORT size_t _olm_encode_group_message( size_t _olm_encode_group_message(
uint8_t version, uint8_t version,
uint32_t message_index, uint32_t message_index,
size_t ciphertext_length, size_t ciphertext_length,
@ -80,7 +76,7 @@ struct _OlmDecodeGroupMessageResults {
/** /**
* Reads the message headers from the input buffer. * Reads the message headers from the input buffer.
*/ */
OLM_EXPORT void _olm_decode_group_message( void _olm_decode_group_message(
const uint8_t *input, size_t input_length, const uint8_t *input, size_t input_length,
size_t mac_length, size_t signature_length, size_t mac_length, size_t signature_length,

View file

@ -27,16 +27,13 @@
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
// Note: exports in this file are only for unit tests. Nobody else should be
// using this externally
#include "olm/olm_export.h"
namespace olm { namespace olm {
/** /**
* The length of the buffer needed to hold a message. * The length of the buffer needed to hold a message.
*/ */
OLM_EXPORT std::size_t encode_message_length( std::size_t encode_message_length(
std::uint32_t counter, std::uint32_t counter,
std::size_t ratchet_key_length, std::size_t ratchet_key_length,
std::size_t ciphertext_length, std::size_t ciphertext_length,
@ -64,7 +61,7 @@ struct MessageReader {
* Writes the message headers into the output buffer. * Writes the message headers into the output buffer.
* Populates the writer struct with pointers into the output buffer. * Populates the writer struct with pointers into the output buffer.
*/ */
OLM_EXPORT void encode_message( void encode_message(
MessageWriter & writer, MessageWriter & writer,
std::uint8_t version, std::uint8_t version,
std::uint32_t counter, std::uint32_t counter,
@ -78,7 +75,7 @@ OLM_EXPORT void encode_message(
* Reads the message headers from the input buffer. * Reads the message headers from the input buffer.
* Populates the reader struct with pointers into the input buffer. * Populates the reader struct with pointers into the input buffer.
*/ */
OLM_EXPORT void decode_message( void decode_message(
MessageReader & reader, MessageReader & reader,
std::uint8_t const * input, std::size_t input_length, std::uint8_t const * input, std::size_t input_length,
std::size_t mac_length std::size_t mac_length

View file

@ -19,12 +19,9 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "olm/error.h"
#include "olm/inbound_group_session.h" #include "olm/inbound_group_session.h"
#include "olm/outbound_group_session.h" #include "olm/outbound_group_session.h"
#include "olm/olm_export.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -39,94 +36,79 @@ typedef struct OlmUtility OlmUtility;
/** Get the version number of the library. /** Get the version number of the library.
* Arguments will be updated if non-null. * Arguments will be updated if non-null.
*/ */
OLM_EXPORT void olm_get_library_version(uint8_t *major, uint8_t *minor, uint8_t *patch); void olm_get_library_version(uint8_t *major, uint8_t *minor, uint8_t *patch);
/** The size of an account object in bytes */ /** The size of an account object in bytes */
OLM_EXPORT size_t olm_account_size(void); size_t olm_account_size(void);
/** The size of a session object in bytes */ /** The size of a session object in bytes */
OLM_EXPORT size_t olm_session_size(void); size_t olm_session_size(void);
/** The size of a utility object in bytes */ /** The size of a utility object in bytes */
OLM_EXPORT size_t olm_utility_size(void); size_t olm_utility_size(void);
/** Initialise an account object using the supplied memory /** Initialise an account object using the supplied memory
* The supplied memory must be at least olm_account_size() bytes */ * The supplied memory must be at least olm_account_size() bytes */
OLM_EXPORT OlmAccount * olm_account( OlmAccount * olm_account(
void * memory void * memory
); );
/** Initialise a session object using the supplied memory /** Initialise a session object using the supplied memory
* The supplied memory must be at least olm_session_size() bytes */ * The supplied memory must be at least olm_session_size() bytes */
OLM_EXPORT OlmSession * olm_session( OlmSession * olm_session(
void * memory void * memory
); );
/** Initialise a utility object using the supplied memory /** Initialise a utility object using the supplied memory
* The supplied memory must be at least olm_utility_size() bytes */ * The supplied memory must be at least olm_utility_size() bytes */
OLM_EXPORT OlmUtility * olm_utility( OlmUtility * olm_utility(
void * memory void * memory
); );
/** The value that olm will return from a function if there was an error */ /** The value that olm will return from a function if there was an error */
OLM_EXPORT size_t olm_error(void); size_t olm_error(void);
/** A null terminated string describing the most recent error to happen to an /** A null terminated string describing the most recent error to happen to an
* account */ * account */
OLM_EXPORT const char * olm_account_last_error( const char * olm_account_last_error(
OlmAccount const * account OlmAccount * account
);
/** An error code describing the most recent error to happen to an account */
OLM_EXPORT enum OlmErrorCode olm_account_last_error_code(
OlmAccount const * account
); );
/** A null terminated string describing the most recent error to happen to a /** A null terminated string describing the most recent error to happen to a
* session */ * session */
OLM_EXPORT const char * olm_session_last_error( const char * olm_session_last_error(
OlmSession const * session OlmSession * session
);
/** An error code describing the most recent error to happen to a session */
OLM_EXPORT enum OlmErrorCode olm_session_last_error_code(
OlmSession const * session
); );
/** A null terminated string describing the most recent error to happen to a /** A null terminated string describing the most recent error to happen to a
* utility */ * utility */
OLM_EXPORT const char * olm_utility_last_error( const char * olm_utility_last_error(
OlmUtility const * utility OlmUtility * utility
);
/** An error code describing the most recent error to happen to a utility */
OLM_EXPORT enum OlmErrorCode olm_utility_last_error_code(
OlmUtility const * utility
); );
/** Clears the memory used to back this account */ /** Clears the memory used to back this account */
OLM_EXPORT size_t olm_clear_account( size_t olm_clear_account(
OlmAccount * account OlmAccount * account
); );
/** Clears the memory used to back this session */ /** Clears the memory used to back this session */
OLM_EXPORT size_t olm_clear_session( size_t olm_clear_session(
OlmSession * session OlmSession * session
); );
/** Clears the memory used to back this utility */ /** Clears the memory used to back this utility */
OLM_EXPORT size_t olm_clear_utility( size_t olm_clear_utility(
OlmUtility * utility OlmUtility * utility
); );
/** Returns the number of bytes needed to store an account */ /** Returns the number of bytes needed to store an account */
OLM_EXPORT size_t olm_pickle_account_length( size_t olm_pickle_account_length(
OlmAccount const * account OlmAccount * account
); );
/** Returns the number of bytes needed to store a session */ /** Returns the number of bytes needed to store a session */
OLM_EXPORT size_t olm_pickle_session_length( size_t olm_pickle_session_length(
OlmSession const * session OlmSession * session
); );
/** Stores an account as a base64 string. Encrypts the account using the /** Stores an account as a base64 string. Encrypts the account using the
@ -134,7 +116,7 @@ OLM_EXPORT size_t olm_pickle_session_length(
* Returns olm_error() on failure. If the pickle output buffer * Returns olm_error() on failure. If the pickle output buffer
* is smaller than olm_pickle_account_length() then * is smaller than olm_pickle_account_length() then
* olm_account_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */ * olm_account_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */
OLM_EXPORT size_t olm_pickle_account( size_t olm_pickle_account(
OlmAccount * account, OlmAccount * account,
void const * key, size_t key_length, void const * key, size_t key_length,
void * pickled, size_t pickled_length void * pickled, size_t pickled_length
@ -145,7 +127,7 @@ OLM_EXPORT size_t olm_pickle_account(
* Returns olm_error() on failure. If the pickle output buffer * Returns olm_error() on failure. If the pickle output buffer
* is smaller than olm_pickle_session_length() then * is smaller than olm_pickle_session_length() then
* olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */ * olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */
OLM_EXPORT size_t olm_pickle_session( size_t olm_pickle_session(
OlmSession * session, OlmSession * session,
void const * key, size_t key_length, void const * key, size_t key_length,
void * pickled, size_t pickled_length void * pickled, size_t pickled_length
@ -157,7 +139,7 @@ OLM_EXPORT size_t olm_pickle_session(
* will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then * will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then
* olm_account_last_error() will be "INVALID_BASE64". The input pickled * olm_account_last_error() will be "INVALID_BASE64". The input pickled
* buffer is destroyed */ * buffer is destroyed */
OLM_EXPORT size_t olm_unpickle_account( size_t olm_unpickle_account(
OlmAccount * account, OlmAccount * account,
void const * key, size_t key_length, void const * key, size_t key_length,
void * pickled, size_t pickled_length void * pickled, size_t pickled_length
@ -169,57 +151,57 @@ OLM_EXPORT size_t olm_unpickle_account(
* will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then * will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then
* olm_session_last_error() will be "INVALID_BASE64". The input pickled * olm_session_last_error() will be "INVALID_BASE64". The input pickled
* buffer is destroyed */ * buffer is destroyed */
OLM_EXPORT size_t olm_unpickle_session( size_t olm_unpickle_session(
OlmSession * session, OlmSession * session,
void const * key, size_t key_length, void const * key, size_t key_length,
void * pickled, size_t pickled_length void * pickled, size_t pickled_length
); );
/** The number of random bytes needed to create an account.*/ /** The number of random bytes needed to create an account.*/
OLM_EXPORT size_t olm_create_account_random_length( size_t olm_create_account_random_length(
OlmAccount const * account OlmAccount * account
); );
/** Creates a new account. Returns olm_error() on failure. If there weren't /** Creates a new account. Returns olm_error() on failure. If there weren't
* enough random bytes then olm_account_last_error() will be * enough random bytes then olm_account_last_error() will be
* "NOT_ENOUGH_RANDOM" */ * "NOT_ENOUGH_RANDOM" */
OLM_EXPORT size_t olm_create_account( size_t olm_create_account(
OlmAccount * account, OlmAccount * account,
void * random, size_t random_length void * random, size_t random_length
); );
/** The size of the output buffer needed to hold the identity keys */ /** The size of the output buffer needed to hold the identity keys */
OLM_EXPORT size_t olm_account_identity_keys_length( size_t olm_account_identity_keys_length(
OlmAccount const * account OlmAccount * account
); );
/** Writes the public parts of the identity keys for the account into the /** 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 output buffer. Returns olm_error() on failure. If the
* identity_keys buffer was too small then olm_account_last_error() will be * identity_keys buffer was too small then olm_account_last_error() will be
* "OUTPUT_BUFFER_TOO_SMALL". */ * "OUTPUT_BUFFER_TOO_SMALL". */
OLM_EXPORT size_t olm_account_identity_keys( size_t olm_account_identity_keys(
OlmAccount * account, OlmAccount * account,
void * identity_keys, size_t identity_key_length void * identity_keys, size_t identity_key_length
); );
/** The length of an ed25519 signature encoded as base64. */ /** The length of an ed25519 signature encoded as base64. */
OLM_EXPORT size_t olm_account_signature_length( size_t olm_account_signature_length(
OlmAccount const * account OlmAccount * account
); );
/** Signs a message with the ed25519 key for this account. Returns olm_error() /** Signs a message with the ed25519 key for this account. Returns olm_error()
* on failure. If the signature buffer was too small then * on failure. If the signature buffer was too small then
* olm_account_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */ * olm_account_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */
OLM_EXPORT size_t olm_account_sign( size_t olm_account_sign(
OlmAccount * account, OlmAccount * account,
void const * message, size_t message_length, void const * message, size_t message_length,
void * signature, size_t signature_length void * signature, size_t signature_length
); );
/** The size of the output buffer needed to hold the one time keys */ /** The size of the output buffer needed to hold the one time keys */
OLM_EXPORT size_t olm_account_one_time_keys_length( size_t olm_account_one_time_keys_length(
OlmAccount const * account OlmAccount * account
); );
/** Writes the public parts of the unpublished one time keys for the account /** Writes the public parts of the unpublished one time keys for the account
@ -240,31 +222,25 @@ OLM_EXPORT size_t olm_account_one_time_keys_length(
* <p> * <p>
* If the one_time_keys buffer was too small then olm_account_last_error() * If the one_time_keys buffer was too small then olm_account_last_error()
* will be "OUTPUT_BUFFER_TOO_SMALL". */ * will be "OUTPUT_BUFFER_TOO_SMALL". */
OLM_EXPORT size_t olm_account_one_time_keys( size_t olm_account_one_time_keys(
OlmAccount * account, OlmAccount * account,
void * one_time_keys, size_t one_time_keys_length void * one_time_keys, size_t one_time_keys_length
); );
/** Marks the current set of one time keys and fallback key as being published /** Marks the current set of one time keys as being published. */
* Once marked as published, the one time keys will no longer be returned by size_t olm_account_mark_keys_as_published(
* olm_account_one_time_keys(), and the fallback key will no longer be returned
* by olm_account_unpublished_fallback_key().
*
* Returns the number of one-time keys that were marked as published. Note that
* this count does not include the fallback key. */
OLM_EXPORT size_t olm_account_mark_keys_as_published(
OlmAccount * account OlmAccount * account
); );
/** The largest number of one time keys this account can store. */ /** The largest number of one time keys this account can store. */
OLM_EXPORT size_t olm_account_max_number_of_one_time_keys( size_t olm_account_max_number_of_one_time_keys(
OlmAccount const * account OlmAccount * account
); );
/** The number of random bytes needed to generate a given number of new one /** The number of random bytes needed to generate a given number of new one
* time keys. */ * time keys. */
OLM_EXPORT size_t olm_account_generate_one_time_keys_random_length( size_t olm_account_generate_one_time_keys_random_length(
OlmAccount const * account, OlmAccount * account,
size_t number_of_keys size_t number_of_keys
); );
@ -272,63 +248,15 @@ OLM_EXPORT size_t olm_account_generate_one_time_keys_random_length(
* by this account exceeds max_number_of_one_time_keys() then the old keys are * 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 * 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". */ * too small then olm_account_last_error() will be "NOT_ENOUGH_RANDOM". */
OLM_EXPORT size_t olm_account_generate_one_time_keys( size_t olm_account_generate_one_time_keys(
OlmAccount * account, OlmAccount * account,
size_t number_of_keys, size_t number_of_keys,
void * random, size_t random_length void * random, size_t random_length
); );
/** The number of random bytes needed to generate a fallback key. */
OLM_EXPORT size_t olm_account_generate_fallback_key_random_length(
OlmAccount const * account
);
/** Generates a new fallback key. Only one previous fallback key is
* stored. Returns olm_error() on error. If the number of random bytes is too
* small then olm_account_last_error() will be "NOT_ENOUGH_RANDOM". */
OLM_EXPORT size_t olm_account_generate_fallback_key(
OlmAccount * account,
void * random, size_t random_length
);
/** The number of bytes needed to hold the fallback key as returned by
* olm_account_fallback_key. */
OLM_EXPORT size_t olm_account_fallback_key_length(
OlmAccount const * account
);
/** Deprecated: use olm_account_unpublished_fallback_key instead */
OLM_EXPORT size_t olm_account_fallback_key(
OlmAccount * account,
void * fallback_key, size_t fallback_key_size
);
/** The number of bytes needed to hold the unpublished fallback key as returned
* by olm_account_unpublished fallback_key. */
OLM_EXPORT size_t olm_account_unpublished_fallback_key_length(
OlmAccount const * account
);
/** Returns the fallback key (if present, and if unpublished) into the
* fallback_key buffer */
OLM_EXPORT size_t olm_account_unpublished_fallback_key(
OlmAccount * account,
void * fallback_key, size_t fallback_key_size
);
/** Forget about the old fallback key. This should be called once you are
* reasonably certain that you will not receive any more messages that use
* the old fallback key (e.g. 5 minutes after the new fallback key has been
* published).
*/
OLM_EXPORT void olm_account_forget_old_fallback_key(
OlmAccount * account
);
/** The number of random bytes needed to create an outbound session */ /** The number of random bytes needed to create an outbound session */
OLM_EXPORT size_t olm_create_outbound_session_random_length( size_t olm_create_outbound_session_random_length(
OlmSession const * session OlmSession * session
); );
/** Creates a new out-bound session for sending messages to a given identity_key /** Creates a new out-bound session for sending messages to a given identity_key
@ -336,9 +264,9 @@ OLM_EXPORT size_t olm_create_outbound_session_random_length(
* decoded as base64 then olm_session_last_error() will be "INVALID_BASE64" * 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 * If there weren't enough random bytes then olm_session_last_error() will
* be "NOT_ENOUGH_RANDOM". */ * be "NOT_ENOUGH_RANDOM". */
OLM_EXPORT size_t olm_create_outbound_session( size_t olm_create_outbound_session(
OlmSession * session, OlmSession * session,
OlmAccount const * account, OlmAccount * account,
void const * their_identity_key, size_t their_identity_key_length, 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 const * their_one_time_key, size_t their_one_time_key_length,
void * random, size_t random_length void * random, size_t random_length
@ -349,19 +277,24 @@ OLM_EXPORT size_t olm_create_outbound_session(
* couldn't be decoded then olm_session_last_error will be "INVALID_BASE64". * couldn't be decoded then olm_session_last_error will be "INVALID_BASE64".
* If the message was for an unsupported protocol version then * If the message was for an unsupported protocol version then
* olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message * olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message
* couldn't be decoded then olm_session_last_error() will be * couldn't be decoded then then olm_session_last_error() will be
* "BAD_MESSAGE_FORMAT". If the message refers to an unknown one time * "BAD_MESSAGE_FORMAT". If the message refers to an unknown one time
* key then olm_session_last_error() will be "BAD_MESSAGE_KEY_ID". */ * key then olm_session_last_error() will be "BAD_MESSAGE_KEY_ID". */
OLM_EXPORT size_t olm_create_inbound_session( size_t olm_create_inbound_session(
OlmSession * session, OlmSession * session,
OlmAccount * account, OlmAccount * account,
void * one_time_key_message, size_t message_length void * one_time_key_message, size_t message_length
); );
/** Same as olm_create_inbound_session, but ensures that the identity key /** Create a new in-bound session for sending/receiving messages from an
* in the pre-key message matches the expected identity key, supplied via the * incoming PRE_KEY message. Returns olm_error() on failure. If the base64
* `their_identity_key` parameter. Fails early if there is no match. */ * couldn't be decoded then olm_session_last_error will be "INVALID_BASE64".
OLM_EXPORT size_t olm_create_inbound_session_from( * 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, OlmSession * session,
OlmAccount * account, OlmAccount * account,
void const * their_identity_key, size_t their_identity_key_length, void const * their_identity_key, size_t their_identity_key_length,
@ -369,30 +302,27 @@ OLM_EXPORT size_t olm_create_inbound_session_from(
); );
/** The length of the buffer needed to return the id for this session. */ /** The length of the buffer needed to return the id for this session. */
OLM_EXPORT size_t olm_session_id_length( size_t olm_session_id_length(
OlmSession const * session OlmSession * session
); );
/** An identifier for this session. Will be the same for both ends of the /** 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() * conversation. If the id buffer is too small then olm_session_last_error()
* will be "OUTPUT_BUFFER_TOO_SMALL". */ * will be "OUTPUT_BUFFER_TOO_SMALL". */
OLM_EXPORT size_t olm_session_id( size_t olm_session_id(
OlmSession * session, OlmSession * session,
void * id, size_t id_length void * id, size_t id_length
); );
OLM_EXPORT int olm_session_has_received_message( int olm_session_has_received_message(
OlmSession const *session OlmSession *session
); );
/** /**
* Write a null-terminated string describing the internal state of an olm * Write a null-terminated string describing the internal state of an olm
* session to the buffer provided for debugging and logging purposes. If the * session to the buffer provided for debugging and logging purposes.
* buffer is not large enough to hold the entire string, it will be truncated
* and will end with "...". A buffer length of 600 will be enough to hold any
* output.
*/ */
OLM_EXPORT void olm_session_describe(OlmSession * session, char *buf, size_t buflen); void olm_session_describe(OlmSession * session, char *buf, size_t buflen);
/** Checks if the PRE_KEY message is for this in-bound session. This can happen /** 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 * if multiple messages are sent to this account before this account sends a
@ -403,7 +333,7 @@ OLM_EXPORT void olm_session_describe(OlmSession * session, char *buf, size_t buf
* unsupported protocol version then olm_session_last_error() will be * unsupported protocol version then olm_session_last_error() will be
* "BAD_MESSAGE_VERSION". If the message couldn't be decoded then then * "BAD_MESSAGE_VERSION". If the message couldn't be decoded then then
* olm_session_last_error() will be "BAD_MESSAGE_FORMAT". */ * olm_session_last_error() will be "BAD_MESSAGE_FORMAT". */
OLM_EXPORT size_t olm_matches_inbound_session( size_t olm_matches_inbound_session(
OlmSession * session, OlmSession * session,
void * one_time_key_message, size_t message_length void * one_time_key_message, size_t message_length
); );
@ -417,7 +347,7 @@ OLM_EXPORT size_t olm_matches_inbound_session(
* unsupported protocol version then olm_session_last_error() will be * unsupported protocol version then olm_session_last_error() will be
* "BAD_MESSAGE_VERSION". If the message couldn't be decoded then then * "BAD_MESSAGE_VERSION". If the message couldn't be decoded then then
* olm_session_last_error() will be "BAD_MESSAGE_FORMAT". */ * olm_session_last_error() will be "BAD_MESSAGE_FORMAT". */
OLM_EXPORT size_t olm_matches_inbound_session_from( size_t olm_matches_inbound_session_from(
OlmSession * session, OlmSession * session,
void const * their_identity_key, size_t their_identity_key_length, void const * their_identity_key, size_t their_identity_key_length,
void * one_time_key_message, size_t message_length void * one_time_key_message, size_t message_length
@ -426,7 +356,7 @@ OLM_EXPORT size_t olm_matches_inbound_session_from(
/** Removes the one time keys that the session used from the account. Returns /** 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 * 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". */ * keys then olm_account_last_error() will be "BAD_MESSAGE_KEY_ID". */
OLM_EXPORT size_t olm_remove_one_time_keys( size_t olm_remove_one_time_keys(
OlmAccount * account, OlmAccount * account,
OlmSession * session OlmSession * session
); );
@ -435,19 +365,19 @@ OLM_EXPORT size_t olm_remove_one_time_keys(
* OLM_MESSAGE_TYPE_PRE_KEY if the message will be a PRE_KEY message. * 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_MESSAGE_TYPE_MESSAGE if the message will be a normal message.
* Returns olm_error on failure. */ * Returns olm_error on failure. */
OLM_EXPORT size_t olm_encrypt_message_type( size_t olm_encrypt_message_type(
OlmSession const * session OlmSession * session
); );
/** The number of random bytes needed to encrypt the next message. */ /** The number of random bytes needed to encrypt the next message. */
OLM_EXPORT size_t olm_encrypt_random_length( size_t olm_encrypt_random_length(
OlmSession const * session OlmSession * session
); );
/** The size of the next message in bytes for the given number of plain-text /** The size of the next message in bytes for the given number of plain-text
* bytes. */ * bytes. */
OLM_EXPORT size_t olm_encrypt_message_length( size_t olm_encrypt_message_length(
OlmSession const * session, OlmSession * session,
size_t plaintext_length size_t plaintext_length
); );
@ -457,7 +387,7 @@ OLM_EXPORT size_t olm_encrypt_message_length(
* olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". If there * olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". If there
* weren't enough random bytes then olm_session_last_error() will be * weren't enough random bytes then olm_session_last_error() will be
* "NOT_ENOUGH_RANDOM". */ * "NOT_ENOUGH_RANDOM". */
OLM_EXPORT size_t olm_encrypt( size_t olm_encrypt(
OlmSession * session, OlmSession * session,
void const * plaintext, size_t plaintext_length, void const * plaintext, size_t plaintext_length,
void * random, size_t random_length, void * random, size_t random_length,
@ -472,7 +402,7 @@ OLM_EXPORT size_t olm_encrypt(
* protocol then olm_session_last_error() will be "BAD_MESSAGE_VERSION". * 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 * If the message couldn't be decoded then olm_session_last_error() will be
* "BAD_MESSAGE_FORMAT". */ * "BAD_MESSAGE_FORMAT". */
OLM_EXPORT size_t olm_decrypt_max_plaintext_length( size_t olm_decrypt_max_plaintext_length(
OlmSession * session, OlmSession * session,
size_t message_type, size_t message_type,
void * message, size_t message_length void * message, size_t message_length
@ -489,7 +419,7 @@ OLM_EXPORT size_t olm_decrypt_max_plaintext_length(
* olm_session_last_error() will be BAD_MESSAGE_FORMAT". * olm_session_last_error() will be BAD_MESSAGE_FORMAT".
* If the MAC on the message was invalid then olm_session_last_error() will * If the MAC on the message was invalid then olm_session_last_error() will
* be "BAD_MESSAGE_MAC". */ * be "BAD_MESSAGE_MAC". */
OLM_EXPORT size_t olm_decrypt( size_t olm_decrypt(
OlmSession * session, OlmSession * session,
size_t message_type, size_t message_type,
void * message, size_t message_length, void * message, size_t message_length,
@ -497,14 +427,14 @@ OLM_EXPORT size_t olm_decrypt(
); );
/** The length of the buffer needed to hold the SHA-256 hash. */ /** The length of the buffer needed to hold the SHA-256 hash. */
OLM_EXPORT size_t olm_sha256_length( size_t olm_sha256_length(
OlmUtility const * utility OlmUtility * utility
); );
/** Calculates the SHA-256 hash of the input and encodes it as base64. If the /** Calculates the SHA-256 hash of the input and encodes it as base64. If the
* output buffer is smaller than olm_sha256_length() then * output buffer is smaller than olm_sha256_length() then
* olm_utility_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". */ * olm_utility_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". */
OLM_EXPORT size_t olm_sha256( size_t olm_sha256(
OlmUtility * utility, OlmUtility * utility,
void const * input, size_t input_length, void const * input, size_t input_length,
void * output, size_t output_length void * output, size_t output_length
@ -513,7 +443,7 @@ OLM_EXPORT size_t olm_sha256(
/** Verify an ed25519 signature. If the key was too small then /** Verify an ed25519 signature. If the key was too small then
* olm_utility_last_error() will be "INVALID_BASE64". If the signature was invalid * olm_utility_last_error() will be "INVALID_BASE64". If the signature was invalid
* then olm_utility_last_error() will be "BAD_MESSAGE_MAC". */ * then olm_utility_last_error() will be "BAD_MESSAGE_MAC". */
OLM_EXPORT size_t olm_ed25519_verify( size_t olm_ed25519_verify(
OlmUtility * utility, OlmUtility * utility,
void const * key, size_t key_length, void const * key, size_t key_length,
void const * message, size_t message_length, void const * message, size_t message_length,

View file

@ -1,42 +0,0 @@
#ifndef OLM_EXPORT_H
#define OLM_EXPORT_H
#ifdef OLM_STATIC_DEFINE
# define OLM_EXPORT
# define OLM_NO_EXPORT
#else
# ifndef OLM_EXPORT
# ifdef olm_EXPORTS
/* We are building this library */
# define OLM_EXPORT
# else
/* We are using this library */
# define OLM_EXPORT
# endif
# endif
# ifndef OLM_NO_EXPORT
# define OLM_NO_EXPORT
# endif
#endif
#ifndef OLM_DEPRECATED
# define OLM_DEPRECATED __attribute__ ((__deprecated__))
#endif
#ifndef OLM_DEPRECATED_EXPORT
# define OLM_DEPRECATED_EXPORT OLM_EXPORT OLM_DEPRECATED
#endif
#ifndef OLM_DEPRECATED_NO_EXPORT
# define OLM_DEPRECATED_NO_EXPORT OLM_NO_EXPORT OLM_DEPRECATED
#endif
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef OLM_NO_DEPRECATED
# define OLM_NO_DEPRECATED
# endif
#endif
#endif /* OLM_EXPORT_H */

View file

@ -18,10 +18,6 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "olm/error.h"
#include "olm/olm_export.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -29,38 +25,31 @@ extern "C" {
typedef struct OlmOutboundGroupSession OlmOutboundGroupSession; typedef struct OlmOutboundGroupSession OlmOutboundGroupSession;
/** get the size of an outbound group session, in bytes. */ /** get the size of an outbound group session, in bytes. */
OLM_EXPORT size_t olm_outbound_group_session_size(void); size_t olm_outbound_group_session_size(void);
/** /**
* Initialise an outbound group session object using the supplied memory * Initialise an outbound group session object using the supplied memory
* The supplied memory should be at least olm_outbound_group_session_size() * The supplied memory should be at least olm_outbound_group_session_size()
* bytes. * bytes.
*/ */
OLM_EXPORT OlmOutboundGroupSession * olm_outbound_group_session( OlmOutboundGroupSession * olm_outbound_group_session(
void *memory void *memory
); );
/** /**
* A null terminated string describing the most recent error to happen to a * A null terminated string describing the most recent error to happen to a
* group session */ * group session */
OLM_EXPORT const char *olm_outbound_group_session_last_error( const char *olm_outbound_group_session_last_error(
const OlmOutboundGroupSession *session
);
/**
* An error code describing the most recent error to happen to a group
* session */
OLM_EXPORT enum OlmErrorCode olm_outbound_group_session_last_error_code(
const OlmOutboundGroupSession *session const OlmOutboundGroupSession *session
); );
/** Clears the memory used to back this group session */ /** Clears the memory used to back this group session */
OLM_EXPORT size_t olm_clear_outbound_group_session( size_t olm_clear_outbound_group_session(
OlmOutboundGroupSession *session OlmOutboundGroupSession *session
); );
/** Returns the number of bytes needed to store an outbound group session */ /** Returns the number of bytes needed to store an outbound group session */
OLM_EXPORT size_t olm_pickle_outbound_group_session_length( size_t olm_pickle_outbound_group_session_length(
const OlmOutboundGroupSession *session const OlmOutboundGroupSession *session
); );
@ -72,7 +61,7 @@ OLM_EXPORT size_t olm_pickle_outbound_group_session_length(
* is smaller than olm_pickle_outbound_group_session_length() then * is smaller than olm_pickle_outbound_group_session_length() then
* olm_outbound_group_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" * olm_outbound_group_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL"
*/ */
OLM_EXPORT size_t olm_pickle_outbound_group_session( size_t olm_pickle_outbound_group_session(
OlmOutboundGroupSession *session, OlmOutboundGroupSession *session,
void const * key, size_t key_length, void const * key, size_t key_length,
void * pickled, size_t pickled_length void * pickled, size_t pickled_length
@ -88,7 +77,7 @@ OLM_EXPORT size_t olm_pickle_outbound_group_session(
* olm_outbound_group_session_last_error() will be "INVALID_BASE64". The input * olm_outbound_group_session_last_error() will be "INVALID_BASE64". The input
* pickled buffer is destroyed * pickled buffer is destroyed
*/ */
OLM_EXPORT size_t olm_unpickle_outbound_group_session( size_t olm_unpickle_outbound_group_session(
OlmOutboundGroupSession *session, OlmOutboundGroupSession *session,
void const * key, size_t key_length, void const * key, size_t key_length,
void * pickled, size_t pickled_length void * pickled, size_t pickled_length
@ -96,7 +85,7 @@ OLM_EXPORT size_t olm_unpickle_outbound_group_session(
/** The number of random bytes needed to create an outbound group session */ /** The number of random bytes needed to create an outbound group session */
OLM_EXPORT size_t olm_init_outbound_group_session_random_length( size_t olm_init_outbound_group_session_random_length(
const OlmOutboundGroupSession *session const OlmOutboundGroupSession *session
); );
@ -105,7 +94,7 @@ OLM_EXPORT size_t olm_init_outbound_group_session_random_length(
* failure last_error will be set with an error code. The last_error will be * failure last_error will be set with an error code. The last_error will be
* NOT_ENOUGH_RANDOM if the number of random bytes was too small. * NOT_ENOUGH_RANDOM if the number of random bytes was too small.
*/ */
OLM_EXPORT size_t olm_init_outbound_group_session( size_t olm_init_outbound_group_session(
OlmOutboundGroupSession *session, OlmOutboundGroupSession *session,
uint8_t *random, size_t random_length uint8_t *random, size_t random_length
); );
@ -113,7 +102,7 @@ OLM_EXPORT size_t olm_init_outbound_group_session(
/** /**
* The number of bytes that will be created by encrypting a message * The number of bytes that will be created by encrypting a message
*/ */
OLM_EXPORT size_t olm_group_encrypt_message_length( size_t olm_group_encrypt_message_length(
OlmOutboundGroupSession *session, OlmOutboundGroupSession *session,
size_t plaintext_length size_t plaintext_length
); );
@ -124,7 +113,7 @@ OLM_EXPORT size_t olm_group_encrypt_message_length(
* error code. The last_error will be OUTPUT_BUFFER_TOO_SMALL if the output * error code. The last_error will be OUTPUT_BUFFER_TOO_SMALL if the output
* buffer is too small. * buffer is too small.
*/ */
OLM_EXPORT size_t olm_group_encrypt( size_t olm_group_encrypt(
OlmOutboundGroupSession *session, OlmOutboundGroupSession *session,
uint8_t const * plaintext, size_t plaintext_length, uint8_t const * plaintext, size_t plaintext_length,
uint8_t * message, size_t message_length uint8_t * message, size_t message_length
@ -134,7 +123,7 @@ OLM_EXPORT size_t olm_group_encrypt(
/** /**
* Get the number of bytes returned by olm_outbound_group_session_id() * Get the number of bytes returned by olm_outbound_group_session_id()
*/ */
OLM_EXPORT size_t olm_outbound_group_session_id_length( size_t olm_outbound_group_session_id_length(
const OlmOutboundGroupSession *session const OlmOutboundGroupSession *session
); );
@ -146,7 +135,7 @@ OLM_EXPORT size_t olm_outbound_group_session_id_length(
* last_error will be OUTPUT_BUFFER_TOO_SMALL if the id buffer was too * last_error will be OUTPUT_BUFFER_TOO_SMALL if the id buffer was too
* small. * small.
*/ */
OLM_EXPORT size_t olm_outbound_group_session_id( size_t olm_outbound_group_session_id(
OlmOutboundGroupSession *session, OlmOutboundGroupSession *session,
uint8_t * id, size_t id_length uint8_t * id, size_t id_length
); );
@ -157,14 +146,14 @@ OLM_EXPORT size_t olm_outbound_group_session_id(
* Each message is sent with an increasing index; this returns the index for * Each message is sent with an increasing index; this returns the index for
* the next message. * the next message.
*/ */
OLM_EXPORT uint32_t olm_outbound_group_session_message_index( uint32_t olm_outbound_group_session_message_index(
OlmOutboundGroupSession *session OlmOutboundGroupSession *session
); );
/** /**
* Get the number of bytes returned by olm_outbound_group_session_key() * Get the number of bytes returned by olm_outbound_group_session_key()
*/ */
OLM_EXPORT size_t olm_outbound_group_session_key_length( size_t olm_outbound_group_session_key_length(
const OlmOutboundGroupSession *session const OlmOutboundGroupSession *session
); );
@ -178,7 +167,7 @@ OLM_EXPORT size_t olm_outbound_group_session_key_length(
* failure. On failure last_error will be set with an error code. The * failure. On failure last_error will be set with an error code. The
* last_error will be OUTPUT_BUFFER_TOO_SMALL if the buffer was too small. * last_error will be OUTPUT_BUFFER_TOO_SMALL if the buffer was too small.
*/ */
OLM_EXPORT size_t olm_outbound_group_session_key( size_t olm_outbound_group_session_key(
OlmOutboundGroupSession *session, OlmOutboundGroupSession *session,
uint8_t * key, size_t key_length uint8_t * key, size_t key_length
); );

View file

@ -15,25 +15,8 @@
#ifndef OLM_PICKLE_H_ #ifndef OLM_PICKLE_H_
#define OLM_PICKLE_H_ #define OLM_PICKLE_H_
#include <stddef.h>
#include <stdint.h> #include <stdint.h>
/* Convenience macro for checking the return value of internal unpickling
* functions and returning early on failure. */
#ifndef UNPICKLE_OK
#define UNPICKLE_OK(x) do { if (!(x)) return NULL; } while(0)
#endif
/* Convenience macro for failing on corrupted pickles from public
* API unpickling functions. */
#define FAIL_ON_CORRUPTED_PICKLE(pos, session) \
do { \
if (!pos) { \
session->last_error = OLM_CORRUPTED_PICKLE; \
return (size_t)-1; \
} \
} while(0)
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -76,7 +59,7 @@ uint8_t * _olm_pickle_ed25519_public_key(
); );
/** Unpickle the ed25519 public key. Returns a pointer to the next item in the /** Unpickle the ed25519 public key. Returns a pointer to the next item in the
* buffer on success, NULL on error. */ * buffer. */
const uint8_t * _olm_unpickle_ed25519_public_key( const uint8_t * _olm_unpickle_ed25519_public_key(
const uint8_t *pos, const uint8_t *end, const uint8_t *pos, const uint8_t *end,
struct _olm_ed25519_public_key * value struct _olm_ed25519_public_key * value
@ -94,7 +77,7 @@ uint8_t * _olm_pickle_ed25519_key_pair(
); );
/** Unpickle the ed25519 key pair. Returns a pointer to the next item in the /** Unpickle the ed25519 key pair. Returns a pointer to the next item in the
* buffer on success, NULL on error. */ * buffer. */
const uint8_t * _olm_unpickle_ed25519_key_pair( const uint8_t * _olm_unpickle_ed25519_key_pair(
const uint8_t *pos, const uint8_t *end, const uint8_t *pos, const uint8_t *end,
struct _olm_ed25519_key_pair * value struct _olm_ed25519_key_pair * value

View file

@ -21,12 +21,6 @@
#include <cstring> #include <cstring>
#include <cstdint> #include <cstdint>
/* Convenience macro for checking the return value of internal unpickling
* functions and returning early on failure. */
#ifndef UNPICKLE_OK
#define UNPICKLE_OK(x) do { if (!(x)) return nullptr; } while(0)
#endif
namespace olm { namespace olm {
inline std::size_t pickle_length( inline std::size_t pickle_length(
@ -46,23 +40,6 @@ std::uint8_t const * unpickle(
); );
inline std::size_t pickle_length(
const std::uint8_t & value
) {
return 1;
}
std::uint8_t * pickle(
std::uint8_t * pos,
std::uint8_t value
);
std::uint8_t const * unpickle(
std::uint8_t const * pos, std::uint8_t const * end,
std::uint8_t & value
);
inline std::size_t pickle_length( inline std::size_t pickle_length(
const bool & value const bool & value
) { ) {
@ -111,21 +88,11 @@ std::uint8_t const * unpickle(
olm::List<T, max_size> & list olm::List<T, max_size> & list
) { ) {
std::uint32_t size; std::uint32_t size;
pos = unpickle(pos, end, size); pos = unpickle(pos, end, size);
if (!pos) {
return nullptr;
}
while (size-- && pos != end) { while (size-- && pos != end) {
T * value = list.insert(list.end()); T * value = list.insert(list.end());
pos = unpickle(pos, end, *value); pos = unpickle(pos, end, *value);
if (!pos) {
return nullptr;
} }
}
return pos; return pos;
} }

View file

@ -23,10 +23,6 @@
#include "olm/error.h" #include "olm/error.h"
// Note: exports in this file are only for unit tests. Nobody else should be
// using this externally
#include "olm/olm_export.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -35,7 +31,7 @@ extern "C" {
/** /**
* Get the number of bytes needed to encode a pickle of the length given * Get the number of bytes needed to encode a pickle of the length given
*/ */
OLM_EXPORT size_t _olm_enc_output_length(size_t raw_length); size_t _olm_enc_output_length(size_t raw_length);
/** /**
* Get the point in the output buffer that the raw pickle should be written to. * Get the point in the output buffer that the raw pickle should be written to.
@ -45,7 +41,7 @@ OLM_EXPORT size_t _olm_enc_output_length(size_t raw_length);
* base-64 encoding would otherwise overwrite the end of the input before it * base-64 encoding would otherwise overwrite the end of the input before it
* was encoded.) * was encoded.)
*/ */
OLM_EXPORT uint8_t *_olm_enc_output_pos(uint8_t * output, size_t raw_length); uint8_t *_olm_enc_output_pos(uint8_t * output, size_t raw_length);
/** /**
* Encrypt and encode the given pickle in-situ. * Encrypt and encode the given pickle in-situ.
@ -55,7 +51,7 @@ OLM_EXPORT uint8_t *_olm_enc_output_pos(uint8_t * output, size_t raw_length);
* *
* Returns the number of bytes in the encoded pickle. * Returns the number of bytes in the encoded pickle.
*/ */
OLM_EXPORT size_t _olm_enc_output( size_t _olm_enc_output(
uint8_t const * key, size_t key_length, uint8_t const * key, size_t key_length,
uint8_t *pickle, size_t raw_length uint8_t *pickle, size_t raw_length
); );
@ -66,7 +62,7 @@ OLM_EXPORT size_t _olm_enc_output(
* Returns the number of bytes in the decoded pickle, or olm_error() on error, * Returns the number of bytes in the decoded pickle, or olm_error() on error,
* in which case *last_error will be updated, if last_error is non-NULL. * in which case *last_error will be updated, if last_error is non-NULL.
*/ */
OLM_EXPORT size_t _olm_enc_input( size_t _olm_enc_input(
uint8_t const * key, size_t key_length, uint8_t const * key, size_t key_length,
uint8_t * input, size_t b64_length, uint8_t * input, size_t b64_length,
enum OlmErrorCode * last_error enum OlmErrorCode * last_error

View file

@ -19,10 +19,6 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "olm/error.h"
#include "olm/olm_export.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -30,55 +26,49 @@ extern "C" {
typedef struct OlmPkEncryption OlmPkEncryption; typedef struct OlmPkEncryption OlmPkEncryption;
/* The size of an encryption object in bytes */ /* The size of an encryption object in bytes */
OLM_EXPORT size_t olm_pk_encryption_size(void); size_t olm_pk_encryption_size(void);
/** Initialise an encryption object using the supplied memory /** Initialise an encryption object using the supplied memory
* The supplied memory must be at least olm_pk_encryption_size() bytes */ * The supplied memory must be at least olm_pk_encryption_size() bytes */
OLM_EXPORT OlmPkEncryption *olm_pk_encryption( OlmPkEncryption *olm_pk_encryption(
void * memory void * memory
); );
/** A null terminated string describing the most recent error to happen to an /** A null terminated string describing the most recent error to happen to an
* encryption object */ * encryption object */
OLM_EXPORT const char * olm_pk_encryption_last_error( const char * olm_pk_encryption_last_error(
const OlmPkEncryption * encryption OlmPkEncryption * encryption
);
/** An error code describing the most recent error to happen to an encryption
* object */
OLM_EXPORT enum OlmErrorCode olm_pk_encryption_last_error_code(
const OlmPkEncryption * encryption
); );
/** Clears the memory used to back this encryption object */ /** Clears the memory used to back this encryption object */
OLM_EXPORT size_t olm_clear_pk_encryption( size_t olm_clear_pk_encryption(
OlmPkEncryption *encryption OlmPkEncryption *encryption
); );
/** Set the recipient's public key for encrypting to */ /** Set the recipient's public key for encrypting to */
OLM_EXPORT size_t olm_pk_encryption_set_recipient_key( size_t olm_pk_encryption_set_recipient_key(
OlmPkEncryption *encryption, OlmPkEncryption *encryption,
void const *public_key, size_t public_key_length void const *public_key, size_t public_key_length
); );
/** Get the length of the ciphertext that will correspond to a plaintext of the /** Get the length of the ciphertext that will correspond to a plaintext of the
* given length. */ * given length. */
OLM_EXPORT size_t olm_pk_ciphertext_length( size_t olm_pk_ciphertext_length(
const OlmPkEncryption *encryption, OlmPkEncryption *encryption,
size_t plaintext_length size_t plaintext_length
); );
/** Get the length of the message authentication code. */ /** Get the length of the message authentication code. */
OLM_EXPORT size_t olm_pk_mac_length( size_t olm_pk_mac_length(
const OlmPkEncryption *encryption OlmPkEncryption *encryption
); );
/** Get the length of a public or ephemeral key */ /** Get the length of a public or ephemeral key */
OLM_EXPORT size_t olm_pk_key_length(void); size_t olm_pk_key_length(void);
/** The number of random bytes needed to encrypt a message. */ /** The number of random bytes needed to encrypt a message. */
OLM_EXPORT size_t olm_pk_encrypt_random_length( size_t olm_pk_encrypt_random_length(
const OlmPkEncryption *encryption OlmPkEncryption *encryption
); );
/** Encrypt a plaintext for the recipient set using /** Encrypt a plaintext for the recipient set using
@ -91,7 +81,7 @@ OLM_EXPORT size_t olm_pk_encrypt_random_length(
* ephemeral_key buffers were too small then olm_pk_encryption_last_error() * ephemeral_key buffers were too small then olm_pk_encryption_last_error()
* will be "OUTPUT_BUFFER_TOO_SMALL". If there weren't enough random bytes then * will be "OUTPUT_BUFFER_TOO_SMALL". If there weren't enough random bytes then
* olm_pk_encryption_last_error() will be "OLM_INPUT_BUFFER_TOO_SMALL". */ * olm_pk_encryption_last_error() will be "OLM_INPUT_BUFFER_TOO_SMALL". */
OLM_EXPORT size_t olm_pk_encrypt( size_t olm_pk_encrypt(
OlmPkEncryption *encryption, OlmPkEncryption *encryption,
void const * plaintext, size_t plaintext_length, void const * plaintext, size_t plaintext_length,
void * ciphertext, size_t ciphertext_length, void * ciphertext, size_t ciphertext_length,
@ -103,38 +93,32 @@ OLM_EXPORT size_t olm_pk_encrypt(
typedef struct OlmPkDecryption OlmPkDecryption; typedef struct OlmPkDecryption OlmPkDecryption;
/* The size of a decryption object in bytes */ /* The size of a decryption object in bytes */
OLM_EXPORT size_t olm_pk_decryption_size(void); size_t olm_pk_decryption_size(void);
/** Initialise a decryption object using the supplied memory /** Initialise a decryption object using the supplied memory
* The supplied memory must be at least olm_pk_decryption_size() bytes */ * The supplied memory must be at least olm_pk_decryption_size() bytes */
OLM_EXPORT OlmPkDecryption *olm_pk_decryption( OlmPkDecryption *olm_pk_decryption(
void * memory void * memory
); );
/** A null terminated string describing the most recent error to happen to a /** A null terminated string describing the most recent error to happen to a
* decription object */ * decription object */
OLM_EXPORT const char * olm_pk_decryption_last_error( const char * olm_pk_decryption_last_error(
const OlmPkDecryption * decryption OlmPkDecryption * decryption
);
/** An error code describing the most recent error to happen to a decription
* object */
OLM_EXPORT enum OlmErrorCode olm_pk_decryption_last_error_code(
const OlmPkDecryption * decryption
); );
/** Clears the memory used to back this decryption object */ /** Clears the memory used to back this decryption object */
OLM_EXPORT size_t olm_clear_pk_decryption( size_t olm_clear_pk_decryption(
OlmPkDecryption *decryption OlmPkDecryption *decryption
); );
/** Get the number of bytes required to store an olm private key /** Get the number of bytes required to store an olm private key
*/ */
OLM_EXPORT size_t olm_pk_private_key_length(void); size_t olm_pk_private_key_length(void);
/** DEPRECATED: Use olm_pk_private_key_length() /** DEPRECATED: Use olm_pk_private_key_length()
*/ */
OLM_EXPORT size_t olm_pk_generate_key_random_length(void); size_t olm_pk_generate_key_random_length(void);
/** Initialise the key from the private part of a key as returned by /** Initialise the key from the private part of a key as returned by
* olm_pk_get_private_key(). The associated public key will be written to the * olm_pk_get_private_key(). The associated public key will be written to the
@ -146,7 +130,7 @@ OLM_EXPORT size_t olm_pk_generate_key_random_length(void);
* Note that the pubkey is a base64 encoded string, but the private key is * Note that the pubkey is a base64 encoded string, but the private key is
* an unencoded byte array * an unencoded byte array
*/ */
OLM_EXPORT size_t olm_pk_key_from_private( size_t olm_pk_key_from_private(
OlmPkDecryption * decryption, OlmPkDecryption * decryption,
void * pubkey, size_t pubkey_length, void * pubkey, size_t pubkey_length,
const void * privkey, size_t privkey_length const void * privkey, size_t privkey_length
@ -154,15 +138,15 @@ OLM_EXPORT size_t olm_pk_key_from_private(
/** DEPRECATED: Use olm_pk_key_from_private /** DEPRECATED: Use olm_pk_key_from_private
*/ */
OLM_EXPORT size_t olm_pk_generate_key( size_t olm_pk_generate_key(
OlmPkDecryption * decryption, OlmPkDecryption * decryption,
void * pubkey, size_t pubkey_length, void * pubkey, size_t pubkey_length,
const void * privkey, size_t privkey_length const void * privkey, size_t privkey_length
); );
/** Returns the number of bytes needed to store a decryption object. */ /** Returns the number of bytes needed to store a decryption object. */
OLM_EXPORT size_t olm_pickle_pk_decryption_length( size_t olm_pickle_pk_decryption_length(
const OlmPkDecryption * decryption OlmPkDecryption * decryption
); );
/** Stores decryption object as a base64 string. Encrypts the object using the /** Stores decryption object as a base64 string. Encrypts the object using the
@ -170,7 +154,7 @@ OLM_EXPORT size_t olm_pickle_pk_decryption_length(
* Returns olm_error() on failure. If the pickle output buffer * Returns olm_error() on failure. If the pickle output buffer
* is smaller than olm_pickle_pk_decryption_length() then * is smaller than olm_pickle_pk_decryption_length() then
* olm_pk_decryption_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */ * olm_pk_decryption_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */
OLM_EXPORT size_t olm_pickle_pk_decryption( size_t olm_pickle_pk_decryption(
OlmPkDecryption * decryption, OlmPkDecryption * decryption,
void const * key, size_t key_length, void const * key, size_t key_length,
void *pickled, size_t pickled_length void *pickled, size_t pickled_length
@ -183,7 +167,7 @@ OLM_EXPORT size_t olm_pickle_pk_decryption(
* will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then * will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then
* olm_pk_decryption_last_error() will be "INVALID_BASE64". The input pickled * olm_pk_decryption_last_error() will be "INVALID_BASE64". The input pickled
* buffer is destroyed */ * buffer is destroyed */
OLM_EXPORT size_t olm_unpickle_pk_decryption( size_t olm_unpickle_pk_decryption(
OlmPkDecryption * decryption, OlmPkDecryption * decryption,
void const * key, size_t key_length, void const * key, size_t key_length,
void *pickled, size_t pickled_length, void *pickled, size_t pickled_length,
@ -192,8 +176,8 @@ OLM_EXPORT size_t olm_unpickle_pk_decryption(
/** Get the length of the plaintext that will correspond to a ciphertext of the /** Get the length of the plaintext that will correspond to a ciphertext of the
* given length. */ * given length. */
OLM_EXPORT size_t olm_pk_max_plaintext_length( size_t olm_pk_max_plaintext_length(
const OlmPkDecryption * decryption, OlmPkDecryption * decryption,
size_t ciphertext_length size_t ciphertext_length
); );
@ -202,7 +186,7 @@ OLM_EXPORT size_t olm_pk_max_plaintext_length(
* arguments. Returns the length of the plaintext on success. Returns * arguments. Returns the length of the plaintext on success. Returns
* olm_error() on failure. If the plaintext buffer is too small then * olm_error() on failure. If the plaintext buffer is too small then
* olm_pk_encryption_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". */ * olm_pk_encryption_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". */
OLM_EXPORT size_t olm_pk_decrypt( size_t olm_pk_decrypt(
OlmPkDecryption * decryption, OlmPkDecryption * decryption,
void const * ephemeral_key, size_t ephemeral_key_length, void const * ephemeral_key, size_t ephemeral_key_length,
void const * mac, size_t mac_length, void const * mac, size_t mac_length,
@ -218,7 +202,7 @@ OLM_EXPORT size_t olm_pk_decrypt(
* and olm_pk_encryption_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". * and olm_pk_encryption_last_error() will be "OUTPUT_BUFFER_TOO_SMALL".
* Returns the number of bytes written. * Returns the number of bytes written.
*/ */
OLM_EXPORT size_t olm_pk_get_private_key( size_t olm_pk_get_private_key(
OlmPkDecryption * decryption, OlmPkDecryption * decryption,
void *private_key, size_t private_key_length void *private_key, size_t private_key_length
); );
@ -226,28 +210,22 @@ OLM_EXPORT size_t olm_pk_get_private_key(
typedef struct OlmPkSigning OlmPkSigning; typedef struct OlmPkSigning OlmPkSigning;
/* The size of a signing object in bytes */ /* The size of a signing object in bytes */
OLM_EXPORT size_t olm_pk_signing_size(void); size_t olm_pk_signing_size(void);
/** Initialise a signing object using the supplied memory /** Initialise a signing object using the supplied memory
* The supplied memory must be at least olm_pk_signing_size() bytes */ * The supplied memory must be at least olm_pk_signing_size() bytes */
OLM_EXPORT OlmPkSigning *olm_pk_signing( OlmPkSigning *olm_pk_signing(
void * memory void * memory
); );
/** A null terminated string describing the most recent error to happen to a /** A null terminated string describing the most recent error to happen to a
* signing object */ * signing object */
OLM_EXPORT const char * olm_pk_signing_last_error( const char * olm_pk_signing_last_error(
const OlmPkSigning * sign OlmPkSigning * sign
);
/** A null terminated string describing the most recent error to happen to a
* signing object */
OLM_EXPORT enum OlmErrorCode olm_pk_signing_last_error_code(
const OlmPkSigning * sign
); );
/** Clears the memory used to back this signing object */ /** Clears the memory used to back this signing object */
OLM_EXPORT size_t olm_clear_pk_signing( size_t olm_clear_pk_signing(
OlmPkSigning *sign OlmPkSigning *sign
); );
@ -259,7 +237,7 @@ OLM_EXPORT size_t olm_clear_pk_signing(
* buffer is too small then olm_pk_signing_last_error() will be * buffer is too small then olm_pk_signing_last_error() will be
* "INPUT_BUFFER_TOO_SMALL". * "INPUT_BUFFER_TOO_SMALL".
*/ */
OLM_EXPORT size_t olm_pk_signing_key_from_seed( size_t olm_pk_signing_key_from_seed(
OlmPkSigning * sign, OlmPkSigning * sign,
void * pubkey, size_t pubkey_length, void * pubkey, size_t pubkey_length,
const void * seed, size_t seed_length const void * seed, size_t seed_length
@ -268,24 +246,24 @@ OLM_EXPORT size_t olm_pk_signing_key_from_seed(
/** /**
* The size required for the seed for initialising a signing object. * The size required for the seed for initialising a signing object.
*/ */
OLM_EXPORT size_t olm_pk_signing_seed_length(void); size_t olm_pk_signing_seed_length(void);
/** /**
* The size of the public key of a signing object. * The size of the public key of a signing object.
*/ */
OLM_EXPORT size_t olm_pk_signing_public_key_length(void); size_t olm_pk_signing_public_key_length(void);
/** /**
* The size of a signature created by a signing object. * The size of a signature created by a signing object.
*/ */
OLM_EXPORT size_t olm_pk_signature_length(void); size_t olm_pk_signature_length(void);
/** /**
* Sign a message. The signature will be written to the signature * Sign a message. The signature will be written to the signature
* buffer. Returns olm_error() on failure. If the signature buffer is too * buffer. Returns olm_error() on failure. If the signature buffer is too
* small, olm_pk_signing_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". * small, olm_pk_signing_last_error() will be "OUTPUT_BUFFER_TOO_SMALL".
*/ */
OLM_EXPORT size_t olm_pk_sign( size_t olm_pk_sign(
OlmPkSigning *sign, OlmPkSigning *sign,
uint8_t const * message, size_t message_length, uint8_t const * message, size_t message_length,
uint8_t * signature, size_t signature_length uint8_t * signature, size_t signature_length

View file

@ -19,10 +19,6 @@
#include "olm/list.hh" #include "olm/list.hh"
#include "olm/error.h" #include "olm/error.h"
// Note: exports in this file are only for unit tests. Nobody else should be
// using this externally
#include "olm/olm_export.h"
struct _olm_cipher; struct _olm_cipher;
namespace olm { namespace olm {
@ -76,7 +72,7 @@ struct KdfInfo {
}; };
struct OLM_EXPORT Ratchet { struct Ratchet {
Ratchet( Ratchet(
KdfInfo const & kdf_info, KdfInfo const & kdf_info,
@ -98,7 +94,7 @@ struct OLM_EXPORT Ratchet {
/** The sender chain is used to send messages. Each time a new ephemeral /** The sender chain is used to send messages. Each time a new ephemeral
* key is received from the remote server we generate a new sender chain * key is received from the remote server we generate a new sender chain
* with a new ephemeral key when we next send a message. */ * with a new empheral key when we next send a message. */
List<SenderChain, 1> sender_chain; List<SenderChain, 1> sender_chain;
/** The receiver chain is used to decrypt received messages. We store the /** The receiver chain is used to decrypt received messages. We store the
@ -128,12 +124,12 @@ struct OLM_EXPORT Ratchet {
* a given message length. */ * a given message length. */
std::size_t encrypt_output_length( std::size_t encrypt_output_length(
std::size_t plaintext_length std::size_t plaintext_length
) const; );
/** The number of bytes of random data the encrypt method will need to /** The number of bytes of random data the encrypt method will need to
* encrypt a message. This will be 32 bytes if the session needs to * encrypt a message. This will be 32 bytes if the session needs to
* generate a new ephemeral key, or will be 0 bytes otherwise.*/ * generate a new ephemeral key, or will be 0 bytes otherwise.*/
std::size_t encrypt_random_length() const; std::size_t encrypt_random_length();
/** Encrypt some plain-text. Returns the length of the encrypted message /** Encrypt some plain-text. Returns the length of the encrypted message
* or std::size_t(-1) on failure. On failure last_error will be set with * or std::size_t(-1) on failure. On failure last_error will be set with

View file

@ -19,10 +19,6 @@
#include <stddef.h> #include <stddef.h>
#include "olm/error.h"
#include "olm/olm_export.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -37,33 +33,27 @@ typedef struct OlmSAS OlmSAS;
/** A null terminated string describing the most recent error to happen to an /** A null terminated string describing the most recent error to happen to an
* SAS object. */ * SAS object. */
OLM_EXPORT const char * olm_sas_last_error( const char * olm_sas_last_error(
const OlmSAS * sas OlmSAS * sas
);
/** An error code describing the most recent error to happen to an SAS
* object. */
OLM_EXPORT enum OlmErrorCode olm_sas_last_error_code(
const OlmSAS * sas
); );
/** The size of an SAS object in bytes. */ /** The size of an SAS object in bytes. */
OLM_EXPORT size_t olm_sas_size(void); size_t olm_sas_size(void);
/** Initialize an SAS object using the supplied memory. /** Initialize an SAS object using the supplied memory.
* The supplied memory must be at least `olm_sas_size()` bytes. */ * The supplied memory must be at least `olm_sas_size()` bytes. */
OLM_EXPORT OlmSAS * olm_sas( OlmSAS * olm_sas(
void * memory void * memory
); );
/** Clears the memory used to back an SAS object. */ /** Clears the memory used to back an SAS object. */
OLM_EXPORT size_t olm_clear_sas( size_t olm_clear_sas(
OlmSAS * sas OlmSAS * sas
); );
/** The number of random bytes needed to create an SAS object. */ /** The number of random bytes needed to create an SAS object. */
OLM_EXPORT size_t olm_create_sas_random_length( size_t olm_create_sas_random_length(
const OlmSAS * sas OlmSAS * sas
); );
/** Creates a new SAS object. /** Creates a new SAS object.
@ -77,13 +67,13 @@ OLM_EXPORT size_t olm_create_sas_random_length(
* @return `olm_error()` on failure. If there weren't enough random bytes then * @return `olm_error()` on failure. If there weren't enough random bytes then
* `olm_sas_last_error()` will be `NOT_ENOUGH_RANDOM`. * `olm_sas_last_error()` will be `NOT_ENOUGH_RANDOM`.
*/ */
OLM_EXPORT size_t olm_create_sas( size_t olm_create_sas(
OlmSAS * sas, OlmSAS * sas,
void * random, size_t random_length void * random, size_t random_length
); );
/** The size of a public key in bytes. */ /** The size of a public key in bytes. */
OLM_EXPORT size_t olm_sas_pubkey_length(const OlmSAS * sas); size_t olm_sas_pubkey_length(OlmSAS * sas);
/** Get the public key for the SAS object. /** Get the public key for the SAS object.
* *
@ -95,7 +85,7 @@ OLM_EXPORT size_t olm_sas_pubkey_length(const OlmSAS * sas);
* @return `olm_error()` on failure. If the `pubkey` buffer is too small, then * @return `olm_error()` on failure. If the `pubkey` buffer is too small, then
* `olm_sas_last_error()` will be `OUTPUT_BUFFER_TOO_SMALL`. * `olm_sas_last_error()` will be `OUTPUT_BUFFER_TOO_SMALL`.
*/ */
OLM_EXPORT size_t olm_sas_get_pubkey( size_t olm_sas_get_pubkey(
OlmSAS * sas, OlmSAS * sas,
void * pubkey, size_t pubkey_length void * pubkey, size_t pubkey_length
); );
@ -110,20 +100,11 @@ OLM_EXPORT size_t olm_sas_get_pubkey(
* @return `olm_error()` on failure. If the `their_key` buffer is too small, * @return `olm_error()` on failure. If the `their_key` buffer is too small,
* then `olm_sas_last_error()` will be `INPUT_BUFFER_TOO_SMALL`. * then `olm_sas_last_error()` will be `INPUT_BUFFER_TOO_SMALL`.
*/ */
OLM_EXPORT size_t olm_sas_set_their_key( size_t olm_sas_set_their_key(
OlmSAS *sas, OlmSAS *sas,
void * their_key, size_t their_key_length void * their_key, size_t their_key_length
); );
/** Checks if their key was set.
*
* @param[in] sas the SAS object.
*
*/
OLM_EXPORT int olm_sas_is_their_key_set(
const OlmSAS *sas
);
/** Generate bytes to use for the short authentication string. /** Generate bytes to use for the short authentication string.
* *
* @param[in] sas the SAS object. * @param[in] sas the SAS object.
@ -133,11 +114,8 @@ OLM_EXPORT int olm_sas_is_their_key_set(
* @param[out] output the output buffer. * @param[out] output the output buffer.
* @param[in] output_length the size of the output buffer. For hex-based SAS * @param[in] output_length the size of the output buffer. For hex-based SAS
* as in the Matrix spec, this will be 5. * as in the Matrix spec, this will be 5.
*
* @return `olm_error()` on failure. If their key wasn't set then
* `olm_sas_last_error()` will be `SAS_THEIR_KEY_NOT_SET`.
*/ */
OLM_EXPORT size_t olm_sas_generate_bytes( size_t olm_sas_generate_bytes(
OlmSAS * sas, OlmSAS * sas,
const void * info, size_t info_length, const void * info, size_t info_length,
void * output, size_t output_length void * output, size_t output_length
@ -145,8 +123,8 @@ OLM_EXPORT size_t olm_sas_generate_bytes(
/** The size of the message authentication code generated by /** The size of the message authentication code generated by
* olm_sas_calculate_mac()`. */ * olm_sas_calculate_mac()`. */
OLM_EXPORT size_t olm_sas_mac_length( size_t olm_sas_mac_length(
const OlmSAS *sas OlmSAS *sas
); );
/** Generate a message authentication code (MAC) based on the shared secret. /** Generate a message authentication code (MAC) based on the shared secret.
@ -164,16 +142,7 @@ OLM_EXPORT size_t olm_sas_mac_length(
* @return `olm_error()` on failure. If the `mac` buffer is too small, then * @return `olm_error()` on failure. If the `mac` buffer is too small, then
* `olm_sas_last_error()` will be `OUTPUT_BUFFER_TOO_SMALL`. * `olm_sas_last_error()` will be `OUTPUT_BUFFER_TOO_SMALL`.
*/ */
OLM_EXPORT size_t olm_sas_calculate_mac( size_t olm_sas_calculate_mac(
OlmSAS * sas,
const void * input, size_t input_length,
const void * info, size_t info_length,
void * mac, size_t mac_length
);
// A version of the calculate mac function that produces base64 strings that are
// compatible with other base64 implementations.
OLM_EXPORT size_t olm_sas_calculate_mac_fixed_base64(
OlmSAS * sas, OlmSAS * sas,
const void * input, size_t input_length, const void * input, size_t input_length,
const void * info, size_t info_length, const void * info, size_t info_length,
@ -181,7 +150,7 @@ OLM_EXPORT size_t olm_sas_calculate_mac_fixed_base64(
); );
// for compatibility with an old version of Riot // for compatibility with an old version of Riot
OLM_EXPORT size_t olm_sas_calculate_mac_long_kdf( size_t olm_sas_calculate_mac_long_kdf(
OlmSAS * sas, OlmSAS * sas,
const void * input, size_t input_length, const void * input, size_t input_length,
const void * info, size_t info_length, const void * info, size_t info_length,

View file

@ -17,10 +17,6 @@
#include "olm/ratchet.hh" #include "olm/ratchet.hh"
// Note: exports in this file are only for unit tests. Nobody else should be
// using this externally
#include "olm/olm_export.h"
namespace olm { namespace olm {
struct Account; struct Account;
@ -30,7 +26,7 @@ enum struct MessageType {
MESSAGE = 1, MESSAGE = 1,
}; };
struct OLM_EXPORT Session { struct Session {
Session(); Session();
@ -45,7 +41,7 @@ struct OLM_EXPORT Session {
/** The number of random bytes that are needed to create a new outbound /** The number of random bytes that are needed to create a new outbound
* session. This will be 64 bytes since two ephemeral keys are needed. */ * session. This will be 64 bytes since two ephemeral keys are needed. */
std::size_t new_outbound_session_random_length() const; std::size_t new_outbound_session_random_length();
/** Start a new outbound session. Returns std::size_t(-1) on failure. On /** Start a new outbound session. Returns std::size_t(-1) on failure. On
* failure last_error will be set with an error code. The last_error will be * failure last_error will be set with an error code. The last_error will be
@ -68,7 +64,7 @@ struct OLM_EXPORT Session {
); );
/** The number of bytes written by session_id() */ /** The number of bytes written by session_id() */
std::size_t session_id_length() const; std::size_t session_id_length();
/** An identifier for this session. Generated by hashing the public keys /** An identifier for this session. Generated by hashing the public keys
* used to create the session. Returns the length of the session id on * used to create the session. Returns the length of the session id on
@ -88,21 +84,21 @@ struct OLM_EXPORT Session {
bool matches_inbound_session( bool matches_inbound_session(
_olm_curve25519_public_key const * their_identity_key, _olm_curve25519_public_key const * their_identity_key,
std::uint8_t const * pre_key_message, std::size_t message_length std::uint8_t const * pre_key_message, std::size_t message_length
) const; );
/** Whether the next message will be a pre-key message or a normal message. /** Whether the next message will be a pre-key message or a normal message.
* An outbound session will send pre-key messages until it receives a * An outbound session will send pre-key messages until it receives a
* message with a ratchet key. */ * message with a ratchet key. */
MessageType encrypt_message_type() const; MessageType encrypt_message_type();
std::size_t encrypt_message_length( std::size_t encrypt_message_length(
std::size_t plaintext_length std::size_t plaintext_length
) const; );
/** The number of bytes of random data the encrypt method will need to /** The number of bytes of random data the encrypt method will need to
* encrypt a message. This will be 32 bytes if the session needs to * encrypt a message. This will be 32 bytes if the session needs to
* generate a new ephemeral key, or will be 0 bytes otherwise. */ * generate a new ephemeral key, or will be 0 bytes otherwise. */
std::size_t encrypt_random_length() const; std::size_t encrypt_random_length();
/** Encrypt some plain-text. Returns the length of the encrypted message /** Encrypt some plain-text. Returns the length of the encrypted message
* or std::size_t(-1) on failure. On failure last_error will be set with * or std::size_t(-1) on failure. On failure last_error will be set with
@ -157,7 +153,7 @@ std::uint8_t * pickle(
); );
OLM_EXPORT std::uint8_t const * unpickle( std::uint8_t const * unpickle(
std::uint8_t const * pos, std::uint8_t const * end, std::uint8_t const * pos, std::uint8_t const * end,
Session & value Session & value
); );

View file

@ -32,7 +32,7 @@ struct Utility {
OlmErrorCode last_error; OlmErrorCode last_error;
/** The length of a SHA-256 hash in bytes. */ /** The length of a SHA-256 hash in bytes. */
std::size_t sha256_length() const; std::size_t sha256_length();
/** Compute a SHA-256 hash. Returns the length of the SHA-256 hash in bytes /** Compute a SHA-256 hash. Returns the length of the SHA-256 hash in bytes
* on success. Returns std::size_t(-1) on failure. On failure last_error * on success. Returns std::size_t(-1) on failure. On failure last_error

View file

@ -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_ */

138
include/public/olm/cipher.h Normal file
View file

@ -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_ */

202
include/public/olm/crypto.h Normal file
View file

@ -0,0 +1,202 @@
/* 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
/** length of a sha256 hash */
#define SHA256_OUTPUT_LENGTH 32
/** length of a public or private Curve25519 key */
#define CURVE25519_KEY_LENGTH 32
/** length of the shared secret created by a Curve25519 ECDH operation */
#define CURVE25519_SHARED_SECRET_LENGTH 32
/** amount of random data required to create a Curve25519 keypair */
#define CURVE25519_RANDOM_LENGTH CURVE25519_KEY_LENGTH
/** length of a public Ed25519 key */
#define ED25519_PUBLIC_KEY_LENGTH 32
/** length of a private Ed25519 key */
#define ED25519_PRIVATE_KEY_LENGTH 64
/** amount of random data required to create a Ed25519 keypair */
#define ED25519_RANDOM_LENGTH 32
/** length of an Ed25519 signature */
#define ED25519_SIGNATURE_LENGTH 64
/** length of an aes256 key */
#define AES256_KEY_LENGTH 32
/** length of an aes256 initialisation vector */
#define AES256_IV_LENGTH 16
struct _olm_aes256_key {
uint8_t key[AES256_KEY_LENGTH];
};
struct _olm_aes256_iv {
uint8_t iv[AES256_IV_LENGTH];
};
struct _olm_curve25519_public_key {
uint8_t public_key[CURVE25519_KEY_LENGTH];
};
struct _olm_curve25519_private_key {
uint8_t private_key[CURVE25519_KEY_LENGTH];
};
struct _olm_curve25519_key_pair {
struct _olm_curve25519_public_key public_key;
struct _olm_curve25519_private_key private_key;
};
struct _olm_ed25519_public_key {
uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH];
};
struct _olm_ed25519_private_key {
uint8_t private_key[ED25519_PRIVATE_KEY_LENGTH];
};
struct _olm_ed25519_key_pair {
struct _olm_ed25519_public_key public_key;
struct _olm_ed25519_private_key private_key;
};
/** The length of output the aes_encrypt_cbc function will write */
size_t _olm_crypto_aes_encrypt_cbc_length(
size_t input_length
);
/** Encrypts the input using AES256 in CBC mode with PKCS#7 padding.
* The output buffer must be big enough to hold the output including padding */
void _olm_crypto_aes_encrypt_cbc(
const struct _olm_aes256_key *key,
const struct _olm_aes256_iv *iv,
const uint8_t *input, size_t input_length,
uint8_t *output
);
/** Decrypts the input using AES256 in CBC mode. The output buffer must be at
* least the same size as the input buffer. Returns the length of the plaintext
* without padding on success or std::size_t(-1) if the padding is invalid.
*/
size_t _olm_crypto_aes_decrypt_cbc(
const struct _olm_aes256_key *key,
const struct _olm_aes256_iv *iv,
uint8_t const * input, size_t input_length,
uint8_t * output
);
/** Computes SHA-256 of the input. The output buffer must be a least
* SHA256_OUTPUT_LENGTH (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 SHA256_OUTPUT_LENGTH (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
);
/** Generate a curve25519 key pair
* random_32_bytes should be CURVE25519_RANDOM_LENGTH (32) bytes long.
*/
void _olm_crypto_curve25519_generate_key(
uint8_t const * random_32_bytes,
struct _olm_curve25519_key_pair *output
);
/** Create a shared secret using our private key and their public key.
* The output buffer must be at least CURVE25519_SHARED_SECRET_LENGTH (32) bytes long.
*/
void _olm_crypto_curve25519_shared_secret(
const struct _olm_curve25519_key_pair *our_key,
const struct _olm_curve25519_public_key *their_key,
uint8_t * output
);
/** Generate an ed25519 key pair
* random_32_bytes should be ED25519_RANDOM_LENGTH (32) bytes long.
*/
void _olm_crypto_ed25519_generate_key(
uint8_t const * random_bytes,
struct _olm_ed25519_key_pair *output
);
/** Signs the message using our private key.
*
* The output buffer must be at least ED25519_SIGNATURE_LENGTH (64) bytes
* long. */
void _olm_crypto_ed25519_sign(
const struct _olm_ed25519_key_pair *our_key,
const uint8_t * message, size_t message_length,
uint8_t * output
);
/** Verify an ed25519 signature
* The signature input buffer must be ED25519_SIGNATURE_LENGTH (64) bytes long.
* Returns non-zero if the signature is valid. */
int _olm_crypto_ed25519_verify(
const struct _olm_ed25519_public_key *their_key,
const uint8_t * message, size_t message_length,
const uint8_t * signature
);
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* OLM_CRYPTO_H_ */

View file

@ -0,0 +1,72 @@
/* 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 */
OLM_BAD_SESSION_KEY = 11, /*!< Attempt to initialise an inbound group
session from an invalid session key */
OLM_UNKNOWN_MESSAGE_INDEX = 12, /*!< Attempt to decode a message whose
* index is earlier than our earliest
* known session key.
*/
/**
* Attempt to unpickle an account which uses pickle version 1 (which did
* not save enough space for the Ed25519 key; the key should be considered
* compromised. We don't let the user reload the account.
*/
OLM_BAD_LEGACY_ACCOUNT_PICKLE = 13,
/**
* Received message had a bad signature
*/
OLM_BAD_SIGNATURE = 14,
OLM_INPUT_BUFFER_TOO_SMALL = 15,
// Not an error code, just here to pad out the enum past 16 because
// otherwise the compiler warns about a redunant check. If you're
// adding an error code, replace this one!
OLM_ERROR_NOT_INVENTED_YET = 16,
/* remember to update the list of string constants in error.c when updating
* this list. */
};
/** get a string representation of the given error code. */
const char * _olm_error_to_string(enum OlmErrorCode error);
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* OLM_ERROR_H_ */

View file

@ -0,0 +1,235 @@
/* Copyright 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_INBOUND_GROUP_SESSION_H_
#define OLM_INBOUND_GROUP_SESSION_H_
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct OlmInboundGroupSession OlmInboundGroupSession;
/** get the size of an inbound group session, in bytes. */
size_t olm_inbound_group_session_size(void);
/**
* Initialise an inbound group session object using the supplied memory
* The supplied memory should be at least olm_inbound_group_session_size()
* bytes.
*/
OlmInboundGroupSession * olm_inbound_group_session(
void *memory
);
/**
* A null terminated string describing the most recent error to happen to a
* group session */
const char *olm_inbound_group_session_last_error(
const OlmInboundGroupSession *session
);
/** Clears the memory used to back this group session */
size_t olm_clear_inbound_group_session(
OlmInboundGroupSession *session
);
/** Returns the number of bytes needed to store an inbound group session */
size_t olm_pickle_inbound_group_session_length(
const OlmInboundGroupSession *session
);
/**
* Stores a group session as a base64 string. Encrypts the session using the
* supplied key. Returns the length of the session on success.
*
* Returns olm_error() on failure. If the pickle output buffer
* is smaller than olm_pickle_inbound_group_session_length() then
* olm_inbound_group_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL"
*/
size_t olm_pickle_inbound_group_session(
OlmInboundGroupSession *session,
void const * key, size_t key_length,
void * pickled, size_t pickled_length
);
/**
* Loads a group 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_inbound_group_session_last_error() will be
* "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then
* olm_inbound_group_session_last_error() will be "INVALID_BASE64". The input
* pickled buffer is destroyed
*/
size_t olm_unpickle_inbound_group_session(
OlmInboundGroupSession *session,
void const * key, size_t key_length,
void * pickled, size_t pickled_length
);
/**
* Start a new inbound group session, from a key exported from
* olm_outbound_group_session_key
*
* Returns olm_error() on failure. On failure last_error will be set with an
* error code. The last_error will be:
*
* * OLM_INVALID_BASE64 if the session_key is not valid base64
* * OLM_BAD_SESSION_KEY if the session_key is invalid
*/
size_t olm_init_inbound_group_session(
OlmInboundGroupSession *session,
/* base64-encoded keys */
uint8_t const * session_key, size_t session_key_length
);
/**
* Import an inbound group session, from a previous export.
*
* Returns olm_error() on failure. On failure last_error will be set with an
* error code. The last_error will be:
*
* * OLM_INVALID_BASE64 if the session_key is not valid base64
* * OLM_BAD_SESSION_KEY if the session_key is invalid
*/
size_t olm_import_inbound_group_session(
OlmInboundGroupSession *session,
/* base64-encoded keys; note that it will be overwritten with the base64-decoded
data. */
uint8_t const * session_key, size_t session_key_length
);
/**
* Get an upper bound on the number of bytes of plain-text the decrypt method
* will write for a given input message length. The actual size could be
* different due to padding.
*
* The input message buffer is destroyed.
*
* Returns olm_error() on failure.
*/
size_t olm_group_decrypt_max_plaintext_length(
OlmInboundGroupSession *session,
uint8_t * message, size_t message_length
);
/**
* Decrypt a message.
*
* The input message buffer is destroyed.
*
* Returns the length of the decrypted plain-text, or olm_error() on failure.
*
* On failure last_error will be set with an error code. The last_error will
* be:
* * OLM_OUTPUT_BUFFER_TOO_SMALL if the plain-text buffer is too small
* * OLM_INVALID_BASE64 if the message is not valid base-64
* * OLM_BAD_MESSAGE_VERSION if the message was encrypted with an unsupported
* version of the protocol
* * OLM_BAD_MESSAGE_FORMAT if the message headers could not be decoded
* * OLM_BAD_MESSAGE_MAC if the message could not be verified
* * OLM_UNKNOWN_MESSAGE_INDEX if we do not have a session key corresponding to the
* message's index (ie, it was sent before the session key was shared with
* us)
*/
size_t olm_group_decrypt(
OlmInboundGroupSession *session,
/* input; note that it will be overwritten with the base64-decoded
message. */
uint8_t * message, size_t message_length,
/* output */
uint8_t * plaintext, size_t max_plaintext_length,
uint32_t * message_index
);
/**
* Get the number of bytes returned by olm_inbound_group_session_id()
*/
size_t olm_inbound_group_session_id_length(
const OlmInboundGroupSession *session
);
/**
* Get a base64-encoded identifier for this session.
*
* Returns the length of the session id on success or olm_error() on
* failure. On failure last_error will be set with an error code. The
* last_error will be OUTPUT_BUFFER_TOO_SMALL if the id buffer was too
* small.
*/
size_t olm_inbound_group_session_id(
OlmInboundGroupSession *session,
uint8_t * id, size_t id_length
);
/**
* Get the first message index we know how to decrypt.
*/
uint32_t olm_inbound_group_session_first_known_index(
const OlmInboundGroupSession *session
);
/**
* Check if the session has been verified as a valid session.
*
* (A session is verified either because the original session share was signed,
* or because we have subsequently successfully decrypted a message.)
*
* This is mainly intended for the unit tests, currently.
*/
int olm_inbound_group_session_is_verified(
const OlmInboundGroupSession *session
);
/**
* Get the number of bytes returned by olm_export_inbound_group_session()
*/
size_t olm_export_inbound_group_session_length(
const OlmInboundGroupSession *session
);
/**
* Export the base64-encoded ratchet key for this session, at the given index,
* in a format which can be used by olm_import_inbound_group_session
*
* Returns the length of the ratchet key on success or olm_error() on
* failure. On failure last_error will be set with an error code. The
* last_error will be:
* * OUTPUT_BUFFER_TOO_SMALL if the buffer was too small
* * OLM_UNKNOWN_MESSAGE_INDEX if we do not have a session key corresponding to the
* given index (ie, it was sent before the session key was shared with
* us)
*/
size_t olm_export_inbound_group_session(
OlmInboundGroupSession *session,
uint8_t * key, size_t key_length, uint32_t message_index
);
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* OLM_INBOUND_GROUP_SESSION_H_ */

119
include/public/olm/list.hh Normal file
View file

@ -0,0 +1,119 @@
/* 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_LIST_HH_
#define OLM_LIST_HH_
#include <cstddef>
namespace olm {
template<typename T, std::size_t max_size>
class List {
public:
List() : _end(_data) {}
typedef T * iterator;
typedef T const * const_iterator;
T * begin() { return _data; }
T * end() { return _end; }
T const * begin() const { return _data; }
T const * end() const { return _end; }
/**
* Is the list empty?
*/
bool empty() const { return _end == _data; }
/**
* The number of items in the list.
*/
std::size_t size() const { return _end - _data; }
T & operator[](std::size_t index) { return _data[index]; }
T const & operator[](std::size_t index) const { return _data[index]; }
/**
* Erase the item from the list at the given position.
*/
void erase(T * pos) {
--_end;
while (pos != _end) {
*pos = *(pos + 1);
++pos;
}
}
/**
* Make space for an item in the list at a given position.
* If inserting the item makes the list longer than max_size then
* the end of the list is discarded.
* Returns the where the item is inserted.
*/
T * insert(T * pos) {
if (_end != _data + max_size) {
++_end;
} else if (pos == _end) {
--pos;
}
T * tmp = _end - 1;
while (tmp != pos) {
*tmp = *(tmp - 1);
--tmp;
}
return pos;
}
/**
* Make space for an item in the list at the start of the list
*/
T * insert() { return insert(begin()); }
/**
* Insert an item into the list at a given position.
* If inserting the item makes the list longer than max_size then
* the end of the list is discarded.
* Returns the where the item is inserted.
*/
T * insert(T * pos, T const & value) {
pos = insert(pos);
*pos = value;
return pos;
}
List<T, max_size> & operator=(List<T, max_size> const & other) {
if (this == &other) {
return *this;
}
T * this_pos = _data;
T * const other_pos = other._data;
while (other_pos != other._end) {
*this_pos = *other;
++this_pos;
++other_pos;
}
_end = this_pos;
return *this;
}
private:
T * _end;
T _data[max_size];
};
} // namespace olm
#endif /* OLM_LIST_HH_ */

View file

@ -0,0 +1,95 @@
/* Copyright 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_MEGOLM_H_
#define OLM_MEGOLM_H_
/**
* implementation of the Megolm multi-part ratchet used in group chats.
*/
#include <stdint.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* number of bytes in each part of the ratchet; this should be the same as
* the length of the hash function used in the HMAC (32 bytes for us, as we
* use HMAC-SHA-256)
*/
#define MEGOLM_RATCHET_PART_LENGTH 32 /* SHA256_OUTPUT_LENGTH */
/**
* number of parts in the ratchet; the advance() implementations rely on
* this being 4.
*/
#define MEGOLM_RATCHET_PARTS 4
#define MEGOLM_RATCHET_LENGTH (MEGOLM_RATCHET_PARTS * MEGOLM_RATCHET_PART_LENGTH)
typedef struct Megolm {
uint8_t data[MEGOLM_RATCHET_PARTS][MEGOLM_RATCHET_PART_LENGTH];
uint32_t counter;
} Megolm;
/**
* The cipher used in megolm-backed conversations
*
* (AES256 + SHA256, with keys based on an HKDF with info of MEGOLM_KEYS)
*/
extern const struct _olm_cipher *megolm_cipher;
/**
* initialize the megolm ratchet. random_data should be at least
* MEGOLM_RATCHET_LENGTH bytes of randomness.
*/
void megolm_init(Megolm *megolm, uint8_t const *random_data, uint32_t counter);
/** Returns the number of bytes needed to store a megolm */
size_t megolm_pickle_length(const Megolm *megolm);
/**
* Pickle the megolm. Returns a pointer to the next free space in the buffer.
*/
uint8_t * megolm_pickle(const Megolm *megolm, uint8_t *pos);
/**
* Unpickle the megolm. Returns a pointer to the next item in the buffer.
*/
const uint8_t * megolm_unpickle(Megolm *megolm, const uint8_t *pos,
const uint8_t *end);
/** advance the ratchet by one step */
void megolm_advance(Megolm *megolm);
/**
* get the key data in the ratchet. The returned data is
* MEGOLM_RATCHET_LENGTH bytes long.
*/
#define megolm_get_data(megolm) ((const uint8_t *)((megolm)->data))
/** advance the ratchet to a given count */
void megolm_advance_to(Megolm *megolm, uint32_t advance_to);
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* OLM_MEGOLM_H_ */

View file

@ -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_ */

View file

@ -0,0 +1,93 @@
/* Copyright 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.
*/
/**
* functions for encoding and decoding messages in the Olm protocol.
*
* Some of these functions have only C++ bindings, and are declared in
* message.hh; in time, they should probably be converted to plain C and
* declared here.
*/
#ifndef OLM_MESSAGE_H_
#define OLM_MESSAGE_H_
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* The length of the buffer needed to hold a group message.
*/
size_t _olm_encode_group_message_length(
uint32_t chain_index,
size_t ciphertext_length,
size_t mac_length,
size_t signature_length
);
/**
* Writes the message headers into the output buffer.
*
* version: version number of the olm protocol
* message_index: message index
* ciphertext_length: length of the ciphertext
* output: where to write the output. Should be at least
* olm_encode_group_message_length() bytes long.
* ciphertext_ptr: returns the address that the ciphertext
* should be written to, followed by the MAC and the
* signature.
*
* Returns the size of the message, up to the MAC.
*/
size_t _olm_encode_group_message(
uint8_t version,
uint32_t message_index,
size_t ciphertext_length,
uint8_t *output,
uint8_t **ciphertext_ptr
);
struct _OlmDecodeGroupMessageResults {
uint8_t version;
uint32_t message_index;
int has_message_index;
const uint8_t *ciphertext;
size_t ciphertext_length;
};
/**
* Reads the message headers from the input buffer.
*/
void _olm_decode_group_message(
const uint8_t *input, size_t input_length,
size_t mac_length, size_t signature_length,
/* output structure: updated with results */
struct _OlmDecodeGroupMessageResults *results
);
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* OLM_MESSAGE_H_ */

457
include/public/olm/olm.h Normal file
View file

@ -0,0 +1,457 @@
/* 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>
#include "olm/inbound_group_session.h"
#include "olm/outbound_group_session.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;
/** Get the version number of the library.
* Arguments will be updated if non-null.
*/
void olm_get_library_version(uint8_t *major, uint8_t *minor, uint8_t *patch);
/** The size of an account object in bytes */
size_t olm_account_size(void);
/** The size of a session object in bytes */
size_t olm_session_size(void);
/** The size of a utility object in bytes */
size_t olm_utility_size(void);
/** 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(void);
/** 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 there 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.
* <p>
* The returned data is a JSON-formatted object with the single property
* <tt>curve25519</tt>, which is itself an object mapping key id to
* base64-encoded Curve25519 key. For example:
* <pre>
* {
* curve25519: {
* "AAAAAA": "wo76WcYtb0Vk/pBOdmduiGJ0wIEjW4IBMbbQn7aSnTo",
* "AAAAAB": "LRvjo46L1X2vx69sS9QNFD29HWulxrmW11Up5AfAjgU"
* }
* }
* </pre>
* Returns olm_error() on failure.
* <p>
* 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
);
int olm_session_has_received_message(
OlmSession *session
);
/**
* Write a null-terminated string describing the internal state of an olm
* session to the buffer provided for debugging and logging purposes.
*/
void olm_session_describe(OlmSession * session, char *buf, size_t buflen);
/** 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. The one_time_key_message buffer is destroyed. Returns 1 if
* the session matches. Returns 0 if the session does not match. 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. The one_time_key_message buffer is destroyed. Returns 1 if
* the session matches. Returns 0 if the session does not match. 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_utility_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_utility_last_error() will be "INVALID_BASE64". If the signature was invalid
* then olm_utility_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_H_ */

View file

@ -0,0 +1,181 @@
/* Copyright 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_OUTBOUND_GROUP_SESSION_H_
#define OLM_OUTBOUND_GROUP_SESSION_H_
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct OlmOutboundGroupSession OlmOutboundGroupSession;
/** get the size of an outbound group session, in bytes. */
size_t olm_outbound_group_session_size(void);
/**
* Initialise an outbound group session object using the supplied memory
* The supplied memory should be at least olm_outbound_group_session_size()
* bytes.
*/
OlmOutboundGroupSession * olm_outbound_group_session(
void *memory
);
/**
* A null terminated string describing the most recent error to happen to a
* group session */
const char *olm_outbound_group_session_last_error(
const OlmOutboundGroupSession *session
);
/** Clears the memory used to back this group session */
size_t olm_clear_outbound_group_session(
OlmOutboundGroupSession *session
);
/** Returns the number of bytes needed to store an outbound group session */
size_t olm_pickle_outbound_group_session_length(
const OlmOutboundGroupSession *session
);
/**
* Stores a group session as a base64 string. Encrypts the session using the
* supplied key. Returns the length of the session on success.
*
* Returns olm_error() on failure. If the pickle output buffer
* is smaller than olm_pickle_outbound_group_session_length() then
* olm_outbound_group_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL"
*/
size_t olm_pickle_outbound_group_session(
OlmOutboundGroupSession *session,
void const * key, size_t key_length,
void * pickled, size_t pickled_length
);
/**
* Loads a group 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_outbound_group_session_last_error() will be
* "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then
* olm_outbound_group_session_last_error() will be "INVALID_BASE64". The input
* pickled buffer is destroyed
*/
size_t olm_unpickle_outbound_group_session(
OlmOutboundGroupSession *session,
void const * key, size_t key_length,
void * pickled, size_t pickled_length
);
/** The number of random bytes needed to create an outbound group session */
size_t olm_init_outbound_group_session_random_length(
const OlmOutboundGroupSession *session
);
/**
* Start a new outbound group session. Returns olm_error() on failure. On
* failure last_error will be set with an error code. The last_error will be
* NOT_ENOUGH_RANDOM if the number of random bytes was too small.
*/
size_t olm_init_outbound_group_session(
OlmOutboundGroupSession *session,
uint8_t *random, size_t random_length
);
/**
* The number of bytes that will be created by encrypting a message
*/
size_t olm_group_encrypt_message_length(
OlmOutboundGroupSession *session,
size_t plaintext_length
);
/**
* Encrypt some plain-text. Returns the length of the encrypted message or
* olm_error() on failure. On failure last_error will be set with an
* error code. The last_error will be OUTPUT_BUFFER_TOO_SMALL if the output
* buffer is too small.
*/
size_t olm_group_encrypt(
OlmOutboundGroupSession *session,
uint8_t const * plaintext, size_t plaintext_length,
uint8_t * message, size_t message_length
);
/**
* Get the number of bytes returned by olm_outbound_group_session_id()
*/
size_t olm_outbound_group_session_id_length(
const OlmOutboundGroupSession *session
);
/**
* Get a base64-encoded identifier for this session.
*
* Returns the length of the session id on success or olm_error() on
* failure. On failure last_error will be set with an error code. The
* last_error will be OUTPUT_BUFFER_TOO_SMALL if the id buffer was too
* small.
*/
size_t olm_outbound_group_session_id(
OlmOutboundGroupSession *session,
uint8_t * id, size_t id_length
);
/**
* Get the current message index for this session.
*
* Each message is sent with an increasing index; this returns the index for
* the next message.
*/
uint32_t olm_outbound_group_session_message_index(
OlmOutboundGroupSession *session
);
/**
* Get the number of bytes returned by olm_outbound_group_session_key()
*/
size_t olm_outbound_group_session_key_length(
const OlmOutboundGroupSession *session
);
/**
* Get the base64-encoded current ratchet key for this session.
*
* Each message is sent with a different ratchet key. This function returns the
* ratchet key that will be used for the next message.
*
* Returns the length of the ratchet key on success or olm_error() on
* failure. On failure last_error will be set with an error code. The
* last_error will be OUTPUT_BUFFER_TOO_SMALL if the buffer was too small.
*/
size_t olm_outbound_group_session_key(
OlmOutboundGroupSession *session,
uint8_t * key, size_t key_length
);
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* OLM_OUTBOUND_GROUP_SESSION_H_ */

View file

@ -0,0 +1,90 @@
/* 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
struct _olm_ed25519_public_key;
struct _olm_ed25519_key_pair;
#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);
/** Get the number of bytes needed to pickle an ed25519 public key */
size_t _olm_pickle_ed25519_public_key_length(
const struct _olm_ed25519_public_key * value
);
/** Pickle the ed25519 public key. Returns a pointer to the next free space in
* the buffer. */
uint8_t * _olm_pickle_ed25519_public_key(
uint8_t *pos, const struct _olm_ed25519_public_key * value
);
/** Unpickle the ed25519 public key. Returns a pointer to the next item in the
* buffer. */
const uint8_t * _olm_unpickle_ed25519_public_key(
const uint8_t *pos, const uint8_t *end,
struct _olm_ed25519_public_key * value
);
/** Get the number of bytes needed to pickle an ed25519 key pair */
size_t _olm_pickle_ed25519_key_pair_length(
const struct _olm_ed25519_key_pair * value
);
/** Pickle the ed25519 key pair. Returns a pointer to the next free space in
* the buffer. */
uint8_t * _olm_pickle_ed25519_key_pair(
uint8_t *pos, const struct _olm_ed25519_key_pair * value
);
/** Unpickle the ed25519 key pair. Returns a pointer to the next item in the
* buffer. */
const uint8_t * _olm_unpickle_ed25519_key_pair(
const uint8_t *pos, const uint8_t *end,
struct _olm_ed25519_key_pair * value
);
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* OLM_PICKLE_H */

View file

@ -0,0 +1,76 @@
/* Copyright 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.
*/
/* functions for encrypting and decrypting pickled representations of objects */
#ifndef OLM_PICKLE_ENCODING_H_
#define OLM_PICKLE_ENCODING_H_
#include <stddef.h>
#include <stdint.h>
#include "olm/error.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Get the number of bytes needed to encode a pickle of the length given
*/
size_t _olm_enc_output_length(size_t raw_length);
/**
* Get the point in the output buffer that the raw pickle should be written to.
*
* In order that we can use the same buffer for the raw pickle, and the encoded
* pickle, the raw pickle needs to be written at the end of the buffer. (The
* base-64 encoding would otherwise overwrite the end of the input before it
* was encoded.)
*/
uint8_t *_olm_enc_output_pos(uint8_t * output, size_t raw_length);
/**
* Encrypt and encode the given pickle in-situ.
*
* The raw pickle should have been written to enc_output_pos(pickle,
* raw_length).
*
* Returns the number of bytes in the encoded pickle.
*/
size_t _olm_enc_output(
uint8_t const * key, size_t key_length,
uint8_t *pickle, size_t raw_length
);
/**
* Decode and decrypt the given pickle in-situ.
*
* Returns the number of bytes in the decoded pickle, or olm_error() on error,
* in which case *last_error will be updated, if last_error is non-NULL.
*/
size_t _olm_enc_input(
uint8_t const * key, size_t key_length,
uint8_t * input, size_t b64_length,
enum OlmErrorCode * last_error
);
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* OLM_PICKLE_ENCODING_H_ */

276
include/public/olm/pk.h Normal file
View file

@ -0,0 +1,276 @@
/* Copyright 2018, 2019 New Vector 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_PK_H_
#define OLM_PK_H_
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct OlmPkEncryption OlmPkEncryption;
/* The size of an encryption object in bytes */
size_t olm_pk_encryption_size(void);
/** Initialise an encryption object using the supplied memory
* The supplied memory must be at least olm_pk_encryption_size() bytes */
OlmPkEncryption *olm_pk_encryption(
void * memory
);
/** A null terminated string describing the most recent error to happen to an
* encryption object */
const char * olm_pk_encryption_last_error(
OlmPkEncryption * encryption
);
/** Clears the memory used to back this encryption object */
size_t olm_clear_pk_encryption(
OlmPkEncryption *encryption
);
/** Set the recipient's public key for encrypting to */
size_t olm_pk_encryption_set_recipient_key(
OlmPkEncryption *encryption,
void const *public_key, size_t public_key_length
);
/** Get the length of the ciphertext that will correspond to a plaintext of the
* given length. */
size_t olm_pk_ciphertext_length(
OlmPkEncryption *encryption,
size_t plaintext_length
);
/** Get the length of the message authentication code. */
size_t olm_pk_mac_length(
OlmPkEncryption *encryption
);
/** Get the length of a public or ephemeral key */
size_t olm_pk_key_length(void);
/** The number of random bytes needed to encrypt a message. */
size_t olm_pk_encrypt_random_length(
OlmPkEncryption *encryption
);
/** Encrypt a plaintext for the recipient set using
* olm_pk_encryption_set_recipient_key. Writes to the ciphertext, mac, and
* ephemeral_key buffers, whose values should be sent to the recipient. mac is
* a Message Authentication Code to ensure that the data is received and
* decrypted properly. ephemeral_key is the public part of the ephemeral key
* used (together with the recipient's key) to generate a symmetric encryption
* key. Returns olm_error() on failure. If the ciphertext, mac, or
* ephemeral_key buffers were too small then olm_pk_encryption_last_error()
* will be "OUTPUT_BUFFER_TOO_SMALL". If there weren't enough random bytes then
* olm_pk_encryption_last_error() will be "OLM_INPUT_BUFFER_TOO_SMALL". */
size_t olm_pk_encrypt(
OlmPkEncryption *encryption,
void const * plaintext, size_t plaintext_length,
void * ciphertext, size_t ciphertext_length,
void * mac, size_t mac_length,
void * ephemeral_key, size_t ephemeral_key_size,
const void * random, size_t random_length
);
typedef struct OlmPkDecryption OlmPkDecryption;
/* The size of a decryption object in bytes */
size_t olm_pk_decryption_size(void);
/** Initialise a decryption object using the supplied memory
* The supplied memory must be at least olm_pk_decryption_size() bytes */
OlmPkDecryption *olm_pk_decryption(
void * memory
);
/** A null terminated string describing the most recent error to happen to a
* decription object */
const char * olm_pk_decryption_last_error(
OlmPkDecryption * decryption
);
/** Clears the memory used to back this decryption object */
size_t olm_clear_pk_decryption(
OlmPkDecryption *decryption
);
/** Get the number of bytes required to store an olm private key
*/
size_t olm_pk_private_key_length(void);
/** DEPRECATED: Use olm_pk_private_key_length()
*/
size_t olm_pk_generate_key_random_length(void);
/** Initialise the key from the private part of a key as returned by
* olm_pk_get_private_key(). The associated public key will be written to the
* pubkey buffer. Returns olm_error() on failure. If the pubkey buffer is too
* small then olm_pk_decryption_last_error() will be "OUTPUT_BUFFER_TOO_SMALL".
* If the private key was not long enough then olm_pk_decryption_last_error()
* will be "OLM_INPUT_BUFFER_TOO_SMALL".
*
* Note that the pubkey is a base64 encoded string, but the private key is
* an unencoded byte array
*/
size_t olm_pk_key_from_private(
OlmPkDecryption * decryption,
void * pubkey, size_t pubkey_length,
const void * privkey, size_t privkey_length
);
/** DEPRECATED: Use olm_pk_key_from_private
*/
size_t olm_pk_generate_key(
OlmPkDecryption * decryption,
void * pubkey, size_t pubkey_length,
const void * privkey, size_t privkey_length
);
/** Returns the number of bytes needed to store a decryption object. */
size_t olm_pickle_pk_decryption_length(
OlmPkDecryption * decryption
);
/** Stores decryption object as a base64 string. Encrypts the object using the
* supplied key. Returns the length of the pickled object on success.
* Returns olm_error() on failure. If the pickle output buffer
* is smaller than olm_pickle_pk_decryption_length() then
* olm_pk_decryption_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */
size_t olm_pickle_pk_decryption(
OlmPkDecryption * decryption,
void const * key, size_t key_length,
void *pickled, size_t pickled_length
);
/** Loads a decryption object from a pickled base64 string. The associated
* public key will be written to the pubkey buffer. Decrypts the object using
* the supplied key. Returns olm_error() on failure. If the key doesn't
* match the one used to encrypt the account then olm_pk_decryption_last_error()
* will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then
* olm_pk_decryption_last_error() will be "INVALID_BASE64". The input pickled
* buffer is destroyed */
size_t olm_unpickle_pk_decryption(
OlmPkDecryption * decryption,
void const * key, size_t key_length,
void *pickled, size_t pickled_length,
void *pubkey, size_t pubkey_length
);
/** Get the length of the plaintext that will correspond to a ciphertext of the
* given length. */
size_t olm_pk_max_plaintext_length(
OlmPkDecryption * decryption,
size_t ciphertext_length
);
/** Decrypt a ciphertext. The input ciphertext buffer is destroyed. See the
* olm_pk_encrypt function for descriptions of the ephemeral_key and mac
* arguments. Returns the length of the plaintext on success. Returns
* olm_error() on failure. If the plaintext buffer is too small then
* olm_pk_encryption_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". */
size_t olm_pk_decrypt(
OlmPkDecryption * decryption,
void const * ephemeral_key, size_t ephemeral_key_length,
void const * mac, size_t mac_length,
void * ciphertext, size_t ciphertext_length,
void * plaintext, size_t max_plaintext_length
);
/**
* Get the private key for an OlmDecryption object as an unencoded byte array
* private_key must be a pointer to a buffer of at least
* olm_pk_private_key_length() bytes and this length must be passed in
* private_key_length. If the given buffer is too small, returns olm_error()
* and olm_pk_encryption_last_error() will be "OUTPUT_BUFFER_TOO_SMALL".
* Returns the number of bytes written.
*/
size_t olm_pk_get_private_key(
OlmPkDecryption * decryption,
void *private_key, size_t private_key_length
);
typedef struct OlmPkSigning OlmPkSigning;
/* The size of a signing object in bytes */
size_t olm_pk_signing_size(void);
/** Initialise a signing object using the supplied memory
* The supplied memory must be at least olm_pk_signing_size() bytes */
OlmPkSigning *olm_pk_signing(
void * memory
);
/** A null terminated string describing the most recent error to happen to a
* signing object */
const char * olm_pk_signing_last_error(
OlmPkSigning * sign
);
/** Clears the memory used to back this signing object */
size_t olm_clear_pk_signing(
OlmPkSigning *sign
);
/**
* Initialise the signing object with a public/private keypair from a seed. The
* associated public key will be written to the pubkey buffer. Returns
* olm_error() on failure. If the public key buffer is too small then
* olm_pk_signing_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". If the seed
* buffer is too small then olm_pk_signing_last_error() will be
* "INPUT_BUFFER_TOO_SMALL".
*/
size_t olm_pk_signing_key_from_seed(
OlmPkSigning * sign,
void * pubkey, size_t pubkey_length,
const void * seed, size_t seed_length
);
/**
* The size required for the seed for initialising a signing object.
*/
size_t olm_pk_signing_seed_length(void);
/**
* The size of the public key of a signing object.
*/
size_t olm_pk_signing_public_key_length(void);
/**
* The size of a signature created by a signing object.
*/
size_t olm_pk_signature_length(void);
/**
* Sign a message. The signature will be written to the signature
* buffer. Returns olm_error() on failure. If the signature buffer is too
* small, olm_pk_signing_last_error() will be "OUTPUT_BUFFER_TOO_SMALL".
*/
size_t olm_pk_sign(
OlmPkSigning *sign,
uint8_t const * message, size_t message_length,
uint8_t * signature, size_t signature_length
);
#ifdef __cplusplus
}
#endif
#endif /* OLM_PK_H_ */

Some files were not shown because too many files have changed in this diff Show more