diff options
author | dec05eba <dec05eba@protonmail.com> | 2020-11-05 01:45:06 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2020-11-05 01:45:06 +0100 |
commit | 2a8202e74846d191a321cca1202175af9db6107d (patch) | |
tree | a6f455caf07da1186851f343a237a4c4e4484f46 | |
parent | 8efa0ec17d8c262f9c3fd7603e8074f74a053708 (diff) |
216 files changed, 53 insertions, 26980 deletions
@@ -26,4 +26,10 @@ xcuserdata/ *.dSYM.zip *.dSYM Pods/ -*.xcworkspace
\ No newline at end of file +*.xcworkspace + +# Compiled sibs files +sibs-build/ +compile_commands.json +tests/sibs-build/ +tests/compile_commands.json diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 0b049e4..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,121 +0,0 @@ -cmake_minimum_required(VERSION 3.4) - -project(olm VERSION 3.2.1 LANGUAGES CXX C) - -option(OLM_TESTS "Build tests" ON) -option(BUILD_SHARED_LIBS "Build as a shared library" ON) - -add_definitions(-DOLMLIB_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}) -add_definitions(-DOLMLIB_VERSION_MINOR=${PROJECT_VERSION_MINOR}) -add_definitions(-DOLMLIB_VERSION_PATCH=${PROJECT_VERSION_PATCH}) - -set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_C_STANDARD 99) -set(CMAKE_C_STANDARD_REQUIRED ON) -set(CMAKE_POSITION_INDEPENDENT_CODE ON) -set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) - -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release) -endif() - -add_library(olm - src/account.cpp - src/base64.cpp - src/cipher.cpp - src/crypto.cpp - src/memory.cpp - src/message.cpp - src/pickle.cpp - src/ratchet.cpp - src/session.cpp - src/utility.cpp - src/pk.cpp - src/sas.c - - src/ed25519.c - src/error.c - src/inbound_group_session.c - src/megolm.c - src/olm.cpp - src/outbound_group_session.c - src/pickle_encoding.c - - lib/crypto-algorithms/aes.c - lib/crypto-algorithms/sha256.c - lib/curve25519-donna/curve25519-donna.c) -add_library(Olm::Olm ALIAS olm) - -target_include_directories(olm - PUBLIC - $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> - $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/lib) - -set_target_properties(olm PROPERTIES - SOVERSION ${PROJECT_VERSION_MAJOR} - VERSION ${PROJECT_VERSION}) - -set_target_properties(olm PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR} - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) - -# -# Installation -# -include(GNUInstallDirs) -set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/Olm) -install(TARGETS olm - EXPORT olm-targets - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} -) - -# The exported target will be named Olm. -set_target_properties(olm PROPERTIES EXPORT_NAME Olm) -install(FILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/olm/olm.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/olm/outbound_group_session.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/olm/inbound_group_session.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/olm/pk.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/olm/sas.h - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/olm) - -# Export the targets to a script. -install(EXPORT olm-targets - FILE OlmTargets.cmake - NAMESPACE Olm:: - DESTINATION ${INSTALL_CONFIGDIR}) - -# Create a ConfigVersion.cmake file. -include(CMakePackageConfigHelpers) -write_basic_package_version_file( - ${CMAKE_CURRENT_BINARY_DIR}/OlmConfigVersion.cmake - VERSION ${PROJECT_VERSION} - COMPATIBILITY SameMajorVersion) - -configure_package_config_file( - ${CMAKE_CURRENT_LIST_DIR}/cmake/OlmConfig.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/OlmConfig.cmake - INSTALL_DESTINATION ${INSTALL_CONFIGDIR}) - -#Install the config & configversion. -install(FILES - ${CMAKE_CURRENT_BINARY_DIR}/OlmConfig.cmake - ${CMAKE_CURRENT_BINARY_DIR}/OlmConfigVersion.cmake - DESTINATION ${INSTALL_CONFIGDIR}) - -# Register package in user's package registry -export(EXPORT olm-targets - FILE ${CMAKE_CURRENT_BINARY_DIR}/OlmTargets.cmake - NAMESPACE Olm::) -export(PACKAGE Olm) - -if (OLM_TESTS) - add_subdirectory(tests) -endif() diff --git a/Makefile b/Makefile deleted file mode 100644 index 4371c63..0000000 --- a/Makefile +++ /dev/null @@ -1,341 +0,0 @@ -#!/usr/bin/make -f - -include common.mk -VERSION := $(MAJOR).$(MINOR).$(PATCH) -PREFIX ?= /usr/local -BUILD_DIR := build -RELEASE_OPTIMIZE_FLAGS ?= -g -O3 -DEBUG_OPTIMIZE_FLAGS ?= -g -O0 -JS_OPTIMIZE_FLAGS ?= -O3 -FUZZING_OPTIMIZE_FLAGS ?= -O3 -CC = gcc -EMCC = emcc -EMAR = emar -AFL_CC = afl-gcc -AFL_CXX = afl-g++ -AR = ar - -UNAME := $(shell uname) -ifeq ($(UNAME),Darwin) - SO := dylib - OLM_LDFLAGS := -else - SO := so - OLM_LDFLAGS := -Wl,-soname,libolm.so.$(MAJOR) \ - -Wl,--version-script,version_script.ver -endif - -RELEASE_TARGET := $(BUILD_DIR)/libolm.$(SO).$(VERSION) -STATIC_RELEASE_TARGET := $(BUILD_DIR)/libolm.a -DEBUG_TARGET := $(BUILD_DIR)/libolm_debug.$(SO).$(VERSION) -JS_WASM_TARGET := javascript/olm.js -JS_ASMJS_TARGET := javascript/olm_legacy.js -WASM_TARGET := $(BUILD_DIR)/wasm/libolm.a - -JS_EXPORTED_FUNCTIONS := javascript/exported_functions.json -JS_EXTRA_EXPORTED_RUNTIME_METHODS := [ALLOC_STACK] -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 - -SOURCES := $(wildcard src/*.cpp) $(wildcard src/*.c) \ - lib/crypto-algorithms/sha256.c \ - lib/crypto-algorithms/aes.c \ - lib/curve25519-donna/curve25519-donna.c - -FUZZER_SOURCES := $(wildcard fuzzers/fuzz_*.cpp) $(wildcard fuzzers/fuzz_*.c) -TEST_SOURCES := $(wildcard tests/test_*.cpp) $(wildcard tests/test_*.c) - -OBJECTS := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCES))) -RELEASE_OBJECTS := $(addprefix $(BUILD_DIR)/release/,$(OBJECTS)) -DEBUG_OBJECTS := $(addprefix $(BUILD_DIR)/debug/,$(OBJECTS)) -FUZZER_OBJECTS := $(addprefix $(BUILD_DIR)/fuzzers/objects/,$(OBJECTS)) -FUZZER_BINARIES := $(addprefix $(BUILD_DIR)/,$(basename $(FUZZER_SOURCES))) -FUZZER_DEBUG_BINARIES := $(patsubst $(BUILD_DIR)/fuzzers/fuzz_%,$(BUILD_DIR)/fuzzers/debug_%,$(FUZZER_BINARIES)) -TEST_BINARIES := $(patsubst tests/%,$(BUILD_DIR)/tests/%,$(basename $(TEST_SOURCES))) -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. -# They are injected inside the modularised code and -# processed by the optimiser. -JS_PRE := $(wildcard javascript/*pre.js) -JS_POST := javascript/olm_outbound_group_session.js \ - javascript/olm_inbound_group_session.js \ - javascript/olm_pk.js \ - javascript/olm_sas.js \ - javascript/olm_post.js - -# The prefix & suffix are just added onto the start & end -# of what comes out emcc, so are outside of the modularised -# code and not seen by the opimiser. -JS_PREFIX := javascript/olm_prefix.js -JS_SUFFIX := javascript/olm_suffix.js - -DOCS := tracing/README.html \ - docs/megolm.html \ - docs/olm.html \ - docs/signing.html \ - README.html \ - CHANGELOG.html - -CPPFLAGS += -Iinclude -Ilib \ - -DOLMLIB_VERSION_MAJOR=$(MAJOR) -DOLMLIB_VERSION_MINOR=$(MINOR) \ - -DOLMLIB_VERSION_PATCH=$(PATCH) - -# we rely on <stdint.h>, which was introduced in C99 -CFLAGS += -Wall -Werror -std=c99 -CXXFLAGS += -Wall -Werror -std=c++11 -LDFLAGS += -Wall -Werror - -CFLAGS_NATIVE = -fPIC -CXXFLAGS_NATIVE = -fPIC - -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 -# payloads (ie. Matrix messages), but we do need about 128K of heap to encrypt -# a 64K event (enough to store the ciphertext and the plaintext, bearing in -# mind that the plaintext can only be 48K because base64). We also have about -# 36K of statics. So let's have 256K of memory. -# (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 -# we don't use this for the legacy build.) -EMCCFLAGS_WASM += -s TOTAL_STACK=65536 -s TOTAL_MEMORY=262144 - -EMCCFLAGS_ASMJS += -s WASM=0 - -EMCC.c = $(EMCC) $(CFLAGS) $(CPPFLAGS) -c -EMCC.cc = $(EMCC) $(CXXFLAGS) $(CPPFLAGS) -c -EMCC_LINK = $(EMCC) $(LDFLAGS) $(EMCCFLAGS) - -AFL.c = $(AFL_CC) $(CFLAGS) $(CPPFLAGS) -c -AFL.cc = $(AFL_CXX) $(CXXFLAGS) $(CPPFLAGS) -c -AFL_LINK.c = $(AFL_CC) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS) -AFL_LINK.cc = $(AFL_CXX) $(LDFLAGS) $(CXXFLAGS) $(CPPFLAGS) - -# generate .d files when compiling -CPPFLAGS += -MMD - -### per-target variables - -$(RELEASE_OBJECTS): CFLAGS += $(RELEASE_OPTIMIZE_FLAGS) $(CFLAGS_NATIVE) -$(RELEASE_OBJECTS): CXXFLAGS += $(RELEASE_OPTIMIZE_FLAGS) $(CXXFLAGS_NATIVE) -$(RELEASE_TARGET): LDFLAGS += $(RELEASE_OPTIMIZE_FLAGS) - -$(DEBUG_OBJECTS): CFLAGS += $(DEBUG_OPTIMIZE_FLAGS) $(CFLAGS_NATIVE) -$(DEBUG_OBJECTS): CXXFLAGS += $(DEBUG_OPTIMIZE_FLAGS) $(CXXFLAGS_NATIVE) -$(DEBUG_TARGET): LDFLAGS += $(DEBUG_OPTIMIZE_FLAGS) - -$(TEST_BINARIES): CPPFLAGS += -Itests/include -$(TEST_BINARIES): LDFLAGS += $(DEBUG_OPTIMIZE_FLAGS) -L$(BUILD_DIR) - -$(FUZZER_OBJECTS): CFLAGS += $(FUZZER_OPTIMIZE_FLAGS) -$(FUZZER_OBJECTS): CXXFLAGS += $(FUZZER_OPTIMIZE_FLAGS) -$(FUZZER_BINARIES): CPPFLAGS += -Ifuzzers/include -$(FUZZER_BINARIES): LDFLAGS += $(FUZZER_OPTIMIZE_FLAGS) -L$(BUILD_DIR) -$(FUZZER_DEBUG_BINARIES): CPPFLAGS += -Ifuzzers/include -$(FUZZER_DEBUG_BINARIES): LDFLAGS += $(DEBUG_OPTIMIZE_FLAGS) - -$(JS_OBJECTS): CFLAGS += $(JS_OPTIMIZE_FLAGS) -$(JS_OBJECTS): CXXFLAGS += $(JS_OPTIMIZE_FLAGS) -$(JS_WASM_TARGET): LDFLAGS += $(JS_OPTIMIZE_FLAGS) -$(JS_ASMJS_TARGET): LDFLAGS += $(JS_OPTIMIZE_FLAGS) - -### Fix to make mkdir work on windows and linux -ifeq ($(shell echo "check_quotes"),"check_quotes") - WINDOWS := yes -else - WINDOWS := no -endif - -ifeq ($(WINDOWS),yes) - mkdir = mkdir $(subst /,\,$(1)) > nul 2>&1 || (exit 0) -else - mkdir = mkdir -p $(1) -endif - -### top-level targets - -lib: $(RELEASE_TARGET) -.PHONY: lib - -$(RELEASE_TARGET): $(RELEASE_OBJECTS) - $(CXX) $(LDFLAGS) --shared -fPIC \ - $(OLM_LDFLAGS) \ - $(OUTPUT_OPTION) $(RELEASE_OBJECTS) - ln -sf libolm.$(SO).$(VERSION) $(BUILD_DIR)/libolm.$(SO).$(MAJOR) - ln -sf libolm.$(SO).$(VERSION) $(BUILD_DIR)/libolm.$(SO) - -debug: $(DEBUG_TARGET) -.PHONY: debug - -$(DEBUG_TARGET): $(DEBUG_OBJECTS) - $(CXX) $(LDFLAGS) --shared -fPIC \ - $(OLM_LDFLAGS) \ - $(OUTPUT_OPTION) $(DEBUG_OBJECTS) - ln -sf libolm_debug.$(SO).$(VERSION) $(BUILD_DIR)/libolm_debug.$(SO).$(MAJOR) - -static: $(STATIC_RELEASE_TARGET) -.PHONY: static - -$(STATIC_RELEASE_TARGET): $(RELEASE_OBJECTS) - $(AR) rcs $@ $^ - -js: $(JS_WASM_TARGET) $(JS_ASMJS_TARGET) -.PHONY: js - -wasm: $(WASM_TARGET) -.PHONY: wasm - -$(WASM_TARGET): $(WASM_OBJECTS) - $(EMAR) rcs $@ $^ - -# 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 -# and then renaming it. -$(JS_WASM_TARGET): $(JS_OBJECTS) $(JS_PRE) $(JS_POST) $(JS_EXPORTED_FUNCTIONS) $(JS_PREFIX) $(JS_SUFFIX) - EMCC_CLOSURE_ARGS="--externs $(JS_EXTERNS)" $(EMCC_LINK) \ - $(EMCCFLAGS_WASM) \ - $(foreach f,$(JS_PRE),--pre-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 "EXTRA_EXPORTED_RUNTIME_METHODS=$(JS_EXTRA_EXPORTED_RUNTIME_METHODS)" \ - -o $@ $(JS_OBJECTS) - -$(JS_ASMJS_TARGET): $(JS_OBJECTS) $(JS_PRE) $(JS_POST) $(JS_EXPORTED_FUNCTIONS) $(JS_PREFIX) $(JS_SUFFIX) - EMCC_CLOSURE_ARGS="--externs $(JS_EXTERNS)" $(EMCC_LINK) \ - $(EMCCFLAGS_ASMJS) \ - $(foreach f,$(JS_PRE),--pre-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 "EXTRA_EXPORTED_RUNTIME_METHODS=$(JS_EXTRA_EXPORTED_RUNTIME_METHODS)" \ - -o $@ $(JS_OBJECTS) - -build_tests: $(TEST_BINARIES) - -test: build_tests - for i in $(TEST_BINARIES); do \ - echo $$i; \ - $$i || exit $$?; \ - done - -test_mem: build_tests - 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_DEBUG_BINARIES) -.PHONY: fuzzers - -$(JS_EXPORTED_FUNCTIONS): $(PUBLIC_HEADERS) - ./exports.py $^ > $@.tmp - mv $@.tmp $@ - -all: test js lib debug doc -.PHONY: all - -install-headers: $(PUBLIC_HEADERS) - test -d $(DESTDIR)$(PREFIX)/include/olm || $(call mkdir,$(DESTDIR)$(PREFIX)/include/olm) - install $(PUBLIC_HEADERS) $(DESTDIR)$(PREFIX)/include/olm/ -.PHONY: install-headers - -install-debug: debug install-headers - test -d $(DESTDIR)$(PREFIX)/lib || $(call mkdir,$(DESTDIR)$(PREFIX)/lib) - install $(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) -.PHONY: install-debug - -install: lib install-headers - test -d $(DESTDIR)$(PREFIX)/lib || $(call mkdir,$(DESTDIR)$(PREFIX)/lib) - install $(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) -.PHONY: install - -clean:; - rm -rf $(BUILD_DIR) $(DOCS) -.PHONY: clean - -doc: $(DOCS) -.PHONY: doc - -### rules for building objects -$(BUILD_DIR)/release/%.o: %.c - $(call mkdir,$(dir $@)) - $(COMPILE.c) $(OUTPUT_OPTION) $< - -$(BUILD_DIR)/release/%.o: %.cpp - $(call mkdir,$(dir $@)) - $(COMPILE.cc) $(OUTPUT_OPTION) $< - -$(BUILD_DIR)/debug/%.o: %.c - $(call mkdir,$(dir $@)) - $(COMPILE.c) $(OUTPUT_OPTION) $< - -$(BUILD_DIR)/debug/%.o: %.cpp - $(call mkdir,$(dir $@)) - $(COMPILE.cc) $(OUTPUT_OPTION) $< - -$(BUILD_DIR)/javascript/%.o: %.c - $(call mkdir,$(dir $@)) - $(EMCC.c) $(OUTPUT_OPTION) $< - -$(BUILD_DIR)/javascript/%.o: %.cpp - $(call mkdir,$(dir $@)) - $(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) - $(call mkdir,$(dir $@)) - $(LINK.c) -o $@ $< $(DEBUG_OBJECTS) $(LOADLIBES) $(LDLIBS) - -$(BUILD_DIR)/tests/%: tests/%.cpp $(DEBUG_OBJECTS) - $(call mkdir,$(dir $@)) - $(LINK.cc) -o $@ $< $(DEBUG_OBJECTS) $(LOADLIBES) $(LDLIBS) - -$(BUILD_DIR)/fuzzers/objects/%.o: %.c - $(call mkdir,$(dir $@)) - $(AFL.c) $(OUTPUT_OPTION) $< - -$(BUILD_DIR)/fuzzers/objects/%.o: %.cpp - $(call mkdir,$(dir $@)) - $(AFL.cc) $(OUTPUT_OPTION) $< - -$(BUILD_DIR)/fuzzers/fuzz_%: fuzzers/fuzz_%.c $(FUZZER_OBJECTS) - $(AFL_LINK.c) -o $@ $< $(FUZZER_OBJECTS) $(LOADLIBES) $(LDLIBS) - -$(BUILD_DIR)/fuzzers/fuzz_%: fuzzers/fuzz_%.cpp $(FUZZER_OBJECTS) - $(AFL_LINK.cc) -o $@ $< $(FUZZER_OBJECTS) $(LOADLIBES) $(LDLIBS) - -$(BUILD_DIR)/fuzzers/debug_%: fuzzers/fuzz_%.c $(DEBUG_OBJECTS) - $(LINK.c) -o $@ $< $(DEBUG_OBJECTS) $(LOADLIBES) $(LDLIBS) - -$(BUILD_DIR)/fuzzers/debug_%: fuzzers/fuzz_%.cpp $(DEBUG_OBJECTS) - $(LINK.cc) -o $@ $< $(DEBUG_OBJECTS) $(LOADLIBES) $(LDLIBS) - -%.html: %.rst - rst2html $< $@ - -### dependencies - --include $(RELEASE_OBJECTS:.o=.d) --include $(DEBUG_OBJECTS:.o=.d) --include $(JS_OBJECTS:.o=.d) --include $(TEST_BINARIES:=.d) --include $(FUZZER_OBJECTS:.o=.d) --include $(FUZZER_BINARIES:=.d) --include $(FUZZER_DEBUG_BINARIES:=.d) diff --git a/OLMKit.podspec b/OLMKit.podspec deleted file mode 100644 index 413ada8..0000000 --- a/OLMKit.podspec +++ /dev/null @@ -1,63 +0,0 @@ -Pod::Spec.new do |s| - - # The libolm version - MAJOR = 3 - MINOR = 2 - PATCH = 1 - - s.name = "OLMKit" - s.version = "#{MAJOR}.#{MINOR}.#{PATCH}" - s.summary = "An Objective-C wrapper of olm (http://matrix.org/git/olm)" - - s.description = <<-DESC - olm is an implementation of the Double Ratchet cryptographic ratchet in C++ - DESC - - s.homepage = "https://gitlab.matrix.org/matrix-org/olm" - - s.license = { :type => "Apache License, Version 2.0", :file => "LICENSE" } - - s.authors = { "Chris Ballinger" => "chrisballinger@gmail.com", - "matrix.org" => "support@matrix.org" } - - s.ios.deployment_target = "6.0" - s.osx.deployment_target = "10.9" - - # Expose the Objective-C wrapper API of libolm - s.public_header_files = "xcode/OLMKit/*.h" - - s.source = { - :git => "https://gitlab.matrix.org/matrix-org/olm.git", - :tag => s.version.to_s - } - - s.source_files = "xcode/OLMKit/*.{h,m}", "include/**/*.{h,hh}", "src/*.{c,cpp}", "lib/crypto-algorithms/sha256.c", "lib/crypto-algorithms/aes.c", "lib/curve25519-donna/curve25519-donna.c" - s.private_header_files = "xcode/OLMKit/*_Private.h" - - # Those files (including .c) are included by ed25519.c. We do not want to compile them twice - s.preserve_paths = "lib/ed25519/**/*.{h,c}" - - s.library = "c++" - - - # Use the same compiler options for C and C++ as olm/Makefile - - s.compiler_flags = "-g -O3 -DOLMLIB_VERSION_MAJOR=#{MAJOR} -DOLMLIB_VERSION_MINOR=#{MINOR} -DOLMLIB_VERSION_PATCH=#{PATCH}" - - # For headers search paths, manage first the normal installation. Then, use paths used - # when the pod is local - s.xcconfig = { - 'USER_HEADER_SEARCH_PATHS' =>"${PODS_ROOT}/OLMKit/include ${PODS_ROOT}/OLMKit/lib #{File.join(File.dirname(__FILE__), 'include')} #{File.join(File.dirname(__FILE__), 'lib')}" - } - - s.subspec 'olmc' do |olmc| - olmc.source_files = "src/*.{c}", "lib/curve25519-donna.h", "lib/crypto-algorithms/sha256.{h,c}", "lib/crypto-algorithms/aes.{h,c}", "lib/curve25519-donna/curve25519-donna.c" - olmc.compiler_flags = ' -std=c99 -fPIC' - end - - s.subspec 'olmcpp' do |olmcpp| - olmcpp.source_files = "src/*.{cpp}" - olmcpp.compiler_flags = ' -std=c++11 -fPIC' - end - -end diff --git a/android/.DS_Store b/android/.DS_Store Binary files differdeleted file mode 100644 index 5008ddf..0000000 --- a/android/.DS_Store +++ /dev/null diff --git a/android/.gitignore b/android/.gitignore deleted file mode 100644 index 3e4c602..0000000 --- a/android/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -#IDEs -/.idea -*.iml - -#OS -.DS_Store - -#builds -/build -*.apk - -.gradle -/local.properties - -# Native build -/olm-sdk/src/main/obj -/olm-sdk/doc -/olm-sdk/src/main/libs/**/*.so - -# Test -/olm-sdk/src/main/libs/**/gdbserver -/olm-sdk/src/main/libs/**/gdb.setup diff --git a/android/README.rst b/android/README.rst deleted file mode 100644 index 46beaab..0000000 --- a/android/README.rst +++ /dev/null @@ -1,29 +0,0 @@ -OlmLibSdk -========= - -OlmLibSdk exposes an android wrapper to libolm. - -Installation ------------- -Create a libs directory in your project directory -Copy the olm-sdk.aar into it. - -In your build.gradle file, add in the android section:: - - repositories { - flatDir { - dir 'libs' - } - } - -Add in the dependencies category:: - - compile(name: 'olm-sdk', ext: 'aar') - -Development ------------ -import the project from the ``android/`` path. - -The project contains some JNI files and some Java wraper files. - -The project contains some tests under AndroidTests package. diff --git a/android/build.gradle b/android/build.gradle deleted file mode 100644 index ad6a928..0000000 --- a/android/build.gradle +++ /dev/null @@ -1,25 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - repositories { - jcenter() - google() - } - dependencies { - classpath 'com.android.tools.build:gradle:3.1.3' - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files - } -} - -allprojects { - repositories { - jcenter() - google() - } -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/android/gradle.properties b/android/gradle.properties deleted file mode 100644 index b810692..0000000 --- a/android/gradle.properties +++ /dev/null @@ -1,22 +0,0 @@ -## Project-wide Gradle settings. -# -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html -# -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -# Default value: -Xmx10248m -XX:MaxPermSize=256m -# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -# -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true -#Wed Oct 05 11:49:34 CEST 2016 - -#systemProp.https.proxyPort=8080 -#systemProp.http.proxyHost=batproxy -#systemProp.https.proxyHost=batproxy -#systemProp.http.proxyPort=8080 - -org.gradle.configureondemand=false diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar Binary files differdeleted file mode 100644 index 13372ae..0000000 --- a/android/gradle/wrapper/gradle-wrapper.jar +++ /dev/null diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 87043e3..0000000 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Thu Oct 13 09:38:01 CEST 2016 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-all.zip diff --git a/android/gradlew b/android/gradlew deleted file mode 100755 index 9d82f78..0000000 --- a/android/gradlew +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/android/gradlew.bat b/android/gradlew.bat deleted file mode 100644 index 8a0b282..0000000 --- a/android/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/android/olm-sdk/build.gradle b/android/olm-sdk/build.gradle deleted file mode 100644 index 81faf5a..0000000 --- a/android/olm-sdk/build.gradle +++ /dev/null @@ -1,125 +0,0 @@ -import org.apache.tools.ant.taskdefs.condition.Os - -apply plugin: 'com.android.library' - -android { - compileSdkVersion 28 - - defaultConfig { - minSdkVersion 11 - targetSdkVersion 28 - versionCode 321 - versionName "3.2.1" - version "3.2.1" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" - } - buildTypes { - debug { - resValue "string", "git_olm_revision", "\"${gitRevision()}\"" - resValue "string", "git_olm_revision_unix_date", "\"${gitRevisionUnixDate()}\"" - resValue "string", "git_olm_revision_date", "\"${gitRevisionDate()}\"" - } - - release { - resValue "string", "git_olm_revision", "\"${gitRevision()}\"" - resValue "string", "git_olm_revision_unix_date", "\"${gitRevisionUnixDate()}\"" - resValue "string", "git_olm_revision_date", "\"${gitRevisionDate()}\"" - - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } - sourceSets.main { - jniLibs.srcDir 'src/main/libs' - jni.srcDirs = [] - } - - task buildJavaDoc(type: Javadoc) { - source = android.sourceSets.main.java.srcDirs - classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) - destinationDir = file("./doc/") - options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PRIVATE - failOnError false - } - - task ndkBuildNativeRelease(type: Exec, description: 'NDK building..') { - println 'ndkBuildNativeRelease starts..' - workingDir file('src/main') - commandLine getNdkBuildCmd(), 'NDK_DEBUG=0' - } - - task ndkBuildNativeDebug(type: Exec, description: 'NDK building..') { - println 'ndkBuildNativeDebug starts..' - workingDir file('src/main') - commandLine getNdkBuildCmd(), 'NDK_DEBUG=1' - } - - task cleanNative(type: Exec, description: 'Clean NDK build') { - workingDir file('src/main') - commandLine getNdkBuildCmd(), 'clean' - } - - tasks.withType(JavaCompile) { - compileTask -> if (compileTask.name.startsWith('compileDebugJava')) { - println 'test compile: Debug' - compileTask.dependsOn ndkBuildNativeDebug - } else if (compileTask.name.startsWith('compileReleaseJava')) { - println 'test compile: Release' - compileTask.dependsOn ndkBuildNativeRelease - } - compileTask.dependsOn buildJavaDoc - } - - clean.dependsOn cleanNative - - - libraryVariants.all { variant -> - variant.outputs.each { output -> - def outputFile = output.outputFileName - if (outputFile != null && outputFile.endsWith('.aar')) { - output.outputFileName = outputFile.replace(".aar", "-${version}.aar") - } - } - } -} - -def getNdkFolder() { - Properties properties = new Properties() - properties.load(project.rootProject.file('local.properties').newDataInputStream()) - def ndkFolder = properties.getProperty('ndk.dir', null) - if (ndkFolder == null) - throw new GradleException("NDK location missing. Define it with ndk.dir in the local.properties file") - - return ndkFolder -} - -def getNdkBuildCmd() { - def ndkBuildCmd = getNdkFolder() + "/ndk-build" - if (Os.isFamily(Os.FAMILY_WINDOWS)) - ndkBuildCmd += ".cmd" - - return ndkBuildCmd -} - -def gitRevision() { - def cmd = "git rev-parse --short HEAD" - return cmd.execute().text.trim() -} - -def gitRevisionUnixDate() { - def cmd = "git show -s --format=%ct HEAD^{commit}" - return cmd.execute().text.trim() -} - -def gitRevisionDate() { - def cmd = "git show -s --format=%ci HEAD^{commit}" - return cmd.execute().text.trim() -} - -dependencies { - testImplementation 'junit:junit:4.12' - androidTestImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support:support-annotations:28.0.0' - androidTestImplementation 'com.android.support.test:runner:1.0.2' - androidTestImplementation 'com.android.support.test:rules:1.0.2' -} diff --git a/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmAccountTest.java b/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmAccountTest.java deleted file mode 100644 index 44405e3..0000000 --- a/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmAccountTest.java +++ /dev/null @@ -1,493 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016 Vector Creations 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. - */ - -package org.matrix.olm; - -import android.content.Context; -import android.support.test.runner.AndroidJUnit4; -import android.text.TextUtils; -import android.util.Log; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.Map; - -import static android.support.test.InstrumentationRegistry.getInstrumentation; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -@RunWith(AndroidJUnit4.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class OlmAccountTest { - private static final String LOG_TAG = "OlmAccountTest"; - private static final int GENERATION_ONE_TIME_KEYS_NUMBER = 50; - - private static OlmAccount mOlmAccount; - private static OlmManager mOlmManager; - private boolean mIsAccountCreated; - private final String FILE_NAME = "SerialTestFile"; - - @BeforeClass - public static void setUpClass(){ - // load native lib - mOlmManager = new OlmManager(); - - String olmLibVersion = mOlmManager.getOlmLibVersion(); - assertNotNull(olmLibVersion); - String olmSdkVersion = mOlmManager.getDetailedVersion(getInstrumentation().getContext()); - assertNotNull(olmLibVersion); - Log.d(LOG_TAG, "## setUpClass(): Versions - Android Olm SDK = "+olmSdkVersion+" Olm lib ="+olmLibVersion); - } - - @AfterClass - public static void tearDownClass() { - // TBD - } - - @Before - public void setUp() { - if(mIsAccountCreated) { - assertNotNull(mOlmAccount); - } - } - - @After - public void tearDown() { - // TBD - } - - /** - * Basic test: creation and release. - */ - @Test - public void test01CreateReleaseAccount() { - try { - mOlmAccount = new OlmAccount(); - } catch (OlmException e) { - e.printStackTrace(); - assertTrue("OlmAccount failed " + e.getMessage(), false); - } - assertNotNull(mOlmAccount); - - mOlmAccount.releaseAccount(); - assertTrue(0 == mOlmAccount.getOlmAccountId()); - } - - @Test - public void test02CreateAccount() { - try { - mOlmAccount = new OlmAccount(); - } catch (OlmException e) { - e.printStackTrace(); - assertTrue("OlmAccount failed " + e.getMessage(), false); - } - assertNotNull(mOlmAccount); - mIsAccountCreated = true; - } - - @Test - public void test04GetOlmAccountId() { - long olmNativeInstance = mOlmAccount.getOlmAccountId(); - Log.d(LOG_TAG,"## testGetOlmAccountId olmNativeInstance="+olmNativeInstance); - assertTrue(0!=olmNativeInstance); - } - - /** - * Test if {@link OlmAccount#identityKeys()} returns a JSON object - * that contains the following keys: {@link OlmAccount#JSON_KEY_FINGER_PRINT_KEY} - * and {@link OlmAccount#JSON_KEY_IDENTITY_KEY} - */ - @Test - public void test05IdentityKeys() { - Map<String, String> identityKeys = null; - try { - identityKeys = mOlmAccount.identityKeys(); - } catch (Exception e) { - assertTrue("identityKeys failed " + e.getMessage(), false); - } - assertNotNull(identityKeys); - Log.d(LOG_TAG,"## testIdentityKeys Keys="+identityKeys); - - // is JSON_KEY_FINGER_PRINT_KEY present? - String fingerPrintKey = TestHelper.getFingerprintKey(identityKeys); - assertTrue("fingerprint key missing",!TextUtils.isEmpty(fingerPrintKey)); - - // is JSON_KEY_IDENTITY_KEY present? - String identityKey = TestHelper.getIdentityKey(identityKeys); - assertTrue("identity key missing",!TextUtils.isEmpty(identityKey)); - } - - //**************************************************** - //***************** ONE TIME KEYS TESTS ************** - //**************************************************** - @Test - public void test06MaxOneTimeKeys() { - long maxOneTimeKeys = mOlmAccount.maxOneTimeKeys(); - Log.d(LOG_TAG,"## testMaxOneTimeKeys(): maxOneTimeKeys="+maxOneTimeKeys); - - assertTrue(maxOneTimeKeys>0); - } - - /** - * Test one time keys generation. - */ - @Test - public void test07GenerateOneTimeKeys() { - String error = null; - - try { - mOlmAccount.generateOneTimeKeys(GENERATION_ONE_TIME_KEYS_NUMBER); - } catch (Exception e) { - error = e.getMessage(); - } - - assertTrue(null == error); - } - - /** - * Test the generated amount of one time keys = GENERATION_ONE_TIME_KEYS_NUMBER. - */ - @Test - public void test08OneTimeKeysJsonFormat() { - int oneTimeKeysCount = 0; - Map<String, Map<String, String>> oneTimeKeysJson = null; - - try { - oneTimeKeysJson = mOlmAccount.oneTimeKeys(); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - assertNotNull(oneTimeKeysJson); - - try { - Map<String, String> map = oneTimeKeysJson.get(OlmAccount.JSON_KEY_ONE_TIME_KEY); - assertTrue(OlmAccount.JSON_KEY_ONE_TIME_KEY +" object is missing", null!=map); - - // test the count of the generated one time keys: - oneTimeKeysCount = map.size(); - - assertTrue("Expected count="+GENERATION_ONE_TIME_KEYS_NUMBER+" found="+oneTimeKeysCount,GENERATION_ONE_TIME_KEYS_NUMBER==oneTimeKeysCount); - - } catch (Exception e) { - assertTrue("Exception MSg="+e.getMessage(), false); - } - } - - @Test - public void test10RemoveOneTimeKeysForSession() { - OlmSession olmSession = null; - try { - olmSession = new OlmSession(); - } catch (OlmException e) { - assertTrue("Exception Msg="+e.getMessage(), false); - } - long sessionId = olmSession.getOlmSessionId(); - assertTrue(0 != sessionId); - - String errorMessage = null; - - try { - mOlmAccount.removeOneTimeKeys(olmSession); - } catch (Exception e) { - errorMessage = e.getMessage(); - } - assertTrue(null != errorMessage); - - olmSession.releaseSession(); - sessionId = olmSession.getOlmSessionId(); - assertTrue(0 == sessionId); - } - - @Test - public void test11MarkOneTimeKeysAsPublished() { - try { - mOlmAccount.markOneTimeKeysAsPublished(); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - } - - @Test - public void test12SignMessage() { - String clearMsg = "String to be signed by olm"; - String signedMsg = null; - - try { - signedMsg = mOlmAccount.signMessage(clearMsg); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - assertNotNull(signedMsg); - // additional tests are performed in test01VerifyEd25519Signing() - } - - - // ******************************************************** - // ************* SERIALIZATION TEST *********************** - // ******************************************************** - - @Test - public void test13Serialization() { - FileOutputStream fileOutput; - ObjectOutputStream objectOutput; - OlmAccount accountRef = null; - OlmAccount accountDeserial = null; - - try { - accountRef = new OlmAccount(); - } catch (OlmException e) { - assertTrue(e.getMessage(),false); - } - - try { - accountRef.generateOneTimeKeys(GENERATION_ONE_TIME_KEYS_NUMBER); - } catch (Exception e) { - assertTrue(e.getMessage(),false); - } - - // get keys references - Map<String, String> identityKeysRef = null; - - try { - identityKeysRef = accountRef.identityKeys(); - } catch (Exception e) { - assertTrue("identityKeys failed " + e.getMessage(), false); - } - - Map<String, Map<String, String>> oneTimeKeysRef = null; - - try { - oneTimeKeysRef = accountRef.oneTimeKeys(); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - assertNotNull(identityKeysRef); - assertNotNull(oneTimeKeysRef); - - try { - Context context = getInstrumentation().getContext(); - //context.getFilesDir(); - fileOutput = context.openFileOutput(FILE_NAME, Context.MODE_PRIVATE); - - // serialize account - objectOutput = new ObjectOutputStream(fileOutput); - objectOutput.writeObject(accountRef); - objectOutput.flush(); - objectOutput.close(); - - // deserialize account - FileInputStream fileInput = context.openFileInput(FILE_NAME); - ObjectInputStream objectInput = new ObjectInputStream(fileInput); - accountDeserial = (OlmAccount) objectInput.readObject(); - objectInput.close(); - assertNotNull(accountDeserial); - - // get de-serialized keys - Map<String, String> identityKeysDeserial = accountDeserial.identityKeys(); - Map<String, Map<String, String>> oneTimeKeysDeserial = accountDeserial.oneTimeKeys(); - assertNotNull(identityKeysDeserial); - assertNotNull(oneTimeKeysDeserial); - - // compare identity keys - assertTrue(identityKeysDeserial.toString().equals(identityKeysRef.toString())); - - // compare onetime keys - assertTrue(oneTimeKeysDeserial.toString().equals(oneTimeKeysRef.toString())); - - accountRef.releaseAccount(); - accountDeserial.releaseAccount(); - } - catch (FileNotFoundException e) { - Log.e(LOG_TAG, "## test13Serialization(): Exception FileNotFoundException Msg=="+e.getMessage()); - assertTrue("test13Serialization failed " + e.getMessage(), false); - } - catch (ClassNotFoundException e) { - Log.e(LOG_TAG, "## test13Serialization(): Exception ClassNotFoundException Msg==" + e.getMessage()); - assertTrue("test13Serialization failed " + e.getMessage(), false); - } - catch (IOException e) { - Log.e(LOG_TAG, "## test13Serialization(): Exception IOException Msg==" + e.getMessage()); - assertTrue("test13Serialization failed " + e.getMessage(), false); - } - /*catch (OlmException e) { - Log.e(LOG_TAG, "## test13Serialization(): Exception OlmException Msg==" + e.getMessage()); - }*/ - catch (Exception e) { - Log.e(LOG_TAG, "## test13Serialization(): Exception Msg==" + e.getMessage()); - assertTrue("test13Serialization failed " + e.getMessage(), false); - } - } - - - // **************************************************** - // *************** SANITY CHECK TESTS ***************** - // **************************************************** - - @Test - public void test14GenerateOneTimeKeysError() { - // keys number = 0 => no error - - String errorMessage = null; - try { - mOlmAccount.generateOneTimeKeys(0); - } catch (Exception e) { - errorMessage = e.getMessage(); - } - - assertTrue(null == errorMessage); - - // keys number = negative value - errorMessage = null; - try { - mOlmAccount.generateOneTimeKeys(-50); - } catch (Exception e) { - errorMessage = e.getMessage(); - } - - assertTrue(null != errorMessage); - } - - @Test - public void test15RemoveOneTimeKeysForSessionError() { - OlmAccount olmAccount = null; - try { - olmAccount = new OlmAccount(); - } catch (OlmException e) { - assertTrue(e.getMessage(),false); - } - - try { - olmAccount.removeOneTimeKeys(null); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - olmAccount.releaseAccount(); - } - - @Test - public void test16SignMessageError() { - OlmAccount olmAccount = null; - try { - olmAccount = new OlmAccount(); - } catch (OlmException e) { - assertTrue(e.getMessage(),false); - } - String signedMsg = null; - - try { - signedMsg = olmAccount.signMessage(null); - } catch (Exception e) { - } - - assertNull(signedMsg); - - olmAccount.releaseAccount(); - } - - /** - * Create multiple accounts and check that identity keys are still different. - * This test validates random series are provide enough random values. - */ - @Test - public void test17MultipleAccountCreation() { - try { - OlmAccount account1 = new OlmAccount(); - OlmAccount account2 = new OlmAccount(); - OlmAccount account3 = new OlmAccount(); - OlmAccount account4 = new OlmAccount(); - OlmAccount account5 = new OlmAccount(); - OlmAccount account6 = new OlmAccount(); - OlmAccount account7 = new OlmAccount(); - OlmAccount account8 = new OlmAccount(); - OlmAccount account9 = new OlmAccount(); - OlmAccount account10 = new OlmAccount(); - - Map<String, String> identityKeys1 = account1.identityKeys(); - Map<String, String> identityKeys2 = account2.identityKeys(); - Map<String, String> identityKeys3 = account3.identityKeys(); - Map<String, String> identityKeys4 = account4.identityKeys(); - Map<String, String> identityKeys5 = account5.identityKeys(); - Map<String, String> identityKeys6 = account6.identityKeys(); - Map<String, String> identityKeys7 = account7.identityKeys(); - Map<String, String> identityKeys8 = account8.identityKeys(); - Map<String, String> identityKeys9 = account9.identityKeys(); - Map<String, String> identityKeys10 = account10.identityKeys(); - - String identityKey1 = TestHelper.getIdentityKey(identityKeys1); - String identityKey2 = TestHelper.getIdentityKey(identityKeys2); - assertFalse(identityKey1.equals(identityKey2)); - - String identityKey3 = TestHelper.getIdentityKey(identityKeys3); - assertFalse(identityKey2.equals(identityKey3)); - - String identityKey4 = TestHelper.getIdentityKey(identityKeys4); - assertFalse(identityKey3.equals(identityKey4)); - - String identityKey5 = TestHelper.getIdentityKey(identityKeys5); - assertFalse(identityKey4.equals(identityKey5)); - - String identityKey6 = TestHelper.getIdentityKey(identityKeys6); - assertFalse(identityKey5.equals(identityKey6)); - - String identityKey7 = TestHelper.getIdentityKey(identityKeys7); - assertFalse(identityKey6.equals(identityKey7)); - - String identityKey8 = TestHelper.getIdentityKey(identityKeys8); - assertFalse(identityKey7.equals(identityKey8)); - - String identityKey9 = TestHelper.getIdentityKey(identityKeys9); - assertFalse(identityKey8.equals(identityKey9)); - - String identityKey10 = TestHelper.getIdentityKey(identityKeys10); - assertFalse(identityKey9.equals(identityKey10)); - - account1.releaseAccount(); - account2.releaseAccount(); - account3.releaseAccount(); - account4.releaseAccount(); - account5.releaseAccount(); - account6.releaseAccount(); - account7.releaseAccount(); - account8.releaseAccount(); - account9.releaseAccount(); - account10.releaseAccount(); - - } catch (OlmException e) { - assertTrue(e.getMessage(),false); - } - } -} diff --git a/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmGroupSessionTest.java b/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmGroupSessionTest.java deleted file mode 100644 index 69eb0e8..0000000 --- a/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmGroupSessionTest.java +++ /dev/null @@ -1,627 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016 Vector Creations 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. - */ - -package org.matrix.olm; - -import android.content.Context; -import android.support.test.runner.AndroidJUnit4; -import android.text.TextUtils; -import android.util.Log; - -import org.junit.BeforeClass; -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; - - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -import static android.support.test.InstrumentationRegistry.getInstrumentation; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -@RunWith(AndroidJUnit4.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class OlmGroupSessionTest { - private static final String LOG_TAG = "OlmSessionTest"; - private final String FILE_NAME_SERIAL_OUT_SESSION = "SerialOutGroupSession"; - private final String FILE_NAME_SERIAL_IN_SESSION = "SerialInGroupSession"; - - private static OlmManager mOlmManager; - private static OlmOutboundGroupSession mAliceOutboundGroupSession; - private static String mAliceSessionIdentifier; - private static long mAliceMessageIndex; - private static final String CLEAR_MESSAGE1 = "Hello!"; - private static String mAliceToBobMessage; - private static OlmInboundGroupSession mBobInboundGroupSession; - private static String mAliceOutboundSessionKey; - private static String mBobSessionIdentifier; - private static String mBobDecryptedMessage; - - @BeforeClass - public static void setUpClass(){ - // load native lib - mOlmManager = new OlmManager(); - - String version = mOlmManager.getOlmLibVersion(); - assertNotNull(version); - Log.d(LOG_TAG, "## setUpClass(): lib version="+version); - } - - /** - * Basic test: - * - alice creates an outbound group session - * - bob creates an inbound group session with alice's outbound session key - * - alice encrypts a message with its session - * - bob decrypts the encrypted message with its session - * - decrypted message is identical to original alice message - */ - @Test - public void test01CreateOutboundSession() { - // alice creates OUTBOUND GROUP SESSION - try { - mAliceOutboundGroupSession = new OlmOutboundGroupSession(); - } catch (OlmException e) { - assertTrue("Exception in OlmOutboundGroupSession, Exception code=" + e.getExceptionCode(), false); - } - } - - @Test - public void test02GetOutboundGroupSessionIdentifier() { - // test session ID - mAliceSessionIdentifier = null; - - try { - mAliceSessionIdentifier = mAliceOutboundGroupSession.sessionIdentifier(); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - assertNotNull(mAliceSessionIdentifier); - assertTrue(mAliceSessionIdentifier.length() > 0); - } - - @Test - public void test03GetOutboundGroupSessionKey() { - // test session Key - mAliceOutboundSessionKey = null; - - try { - mAliceOutboundSessionKey = mAliceOutboundGroupSession.sessionKey(); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - assertNotNull(mAliceOutboundSessionKey); - assertTrue(mAliceOutboundSessionKey.length() > 0); - } - - @Test - public void test04GetOutboundGroupMessageIndex() { - // test message index before any encryption - mAliceMessageIndex = mAliceOutboundGroupSession.messageIndex(); - assertTrue(0 == mAliceMessageIndex); - } - - @Test - public void test05OutboundGroupEncryptMessage() { - // alice encrypts a message to bob - try { - mAliceToBobMessage = mAliceOutboundGroupSession.encryptMessage(CLEAR_MESSAGE1); - } catch (Exception e) { - assertTrue("Exception in bob encryptMessage, Exception code=" + e.getMessage(), false); - } - assertFalse(TextUtils.isEmpty(mAliceToBobMessage)); - - // test message index after encryption is incremented - mAliceMessageIndex = mAliceOutboundGroupSession.messageIndex(); - assertTrue(1 == mAliceMessageIndex); - } - - @Test - public void test06CreateInboundGroupSession() { - // bob creates INBOUND GROUP SESSION with alice outbound key - try { - mBobInboundGroupSession = new OlmInboundGroupSession(mAliceOutboundSessionKey); - } catch (OlmException e) { - assertTrue("Exception in bob OlmInboundGroupSession, Exception code=" + e.getExceptionCode(), false); - } - } - - @Test - public void test08GetInboundGroupSessionIdentifier() { - // check both session identifiers are equals - mBobSessionIdentifier = null; - - try { - mBobSessionIdentifier = mBobInboundGroupSession.sessionIdentifier(); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - assertFalse(TextUtils.isEmpty(mBobSessionIdentifier)); - } - - @Test - public void test09SessionIdentifiersAreIdentical() { - // check both session identifiers are equals: alice vs bob - assertTrue(mAliceSessionIdentifier.equals(mBobSessionIdentifier)); - } - - @Test - public void test10InboundDecryptMessage() { - mBobDecryptedMessage = null; - OlmInboundGroupSession.DecryptMessageResult result = null; - - try { - result = mBobInboundGroupSession.decryptMessage(mAliceToBobMessage); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - // test decrypted message - mBobDecryptedMessage = result.mDecryptedMessage; - assertFalse(TextUtils.isEmpty(mBobDecryptedMessage)); - assertTrue(0 == result.mIndex); - } - - @Test - public void test11InboundDecryptedMessageIdentical() { - // test decrypted message - assertTrue(mBobDecryptedMessage.equals(CLEAR_MESSAGE1)); - } - - @Test - public void test12ReleaseOutboundSession() { - // release group sessions - mAliceOutboundGroupSession.releaseSession(); - } - - @Test - public void test13ReleaseInboundSession() { - // release group sessions - mBobInboundGroupSession.releaseSession(); - } - - @Test - public void test14CheckUnreleaseedCount() { - assertTrue(mAliceOutboundGroupSession.isReleased()); - assertTrue(mBobInboundGroupSession.isReleased()); - } - - @Test - public void test15SerializeOutboundSession() { - OlmOutboundGroupSession outboundGroupSessionRef=null; - OlmOutboundGroupSession outboundGroupSessionSerial; - - // create one OUTBOUND GROUP SESSION - try { - outboundGroupSessionRef = new OlmOutboundGroupSession(); - } catch (OlmException e) { - assertTrue("Exception in OlmOutboundGroupSession, Exception code=" + e.getExceptionCode(), false); - } - assertNotNull(outboundGroupSessionRef); - - - // serialize alice session - Context context = getInstrumentation().getContext(); - try { - FileOutputStream fileOutput = context.openFileOutput(FILE_NAME_SERIAL_OUT_SESSION, Context.MODE_PRIVATE); - ObjectOutputStream objectOutput = new ObjectOutputStream(fileOutput); - objectOutput.writeObject(outboundGroupSessionRef); - objectOutput.flush(); - objectOutput.close(); - - // deserialize session - FileInputStream fileInput = context.openFileInput(FILE_NAME_SERIAL_OUT_SESSION); - ObjectInputStream objectInput = new ObjectInputStream(fileInput); - outboundGroupSessionSerial = (OlmOutboundGroupSession) objectInput.readObject(); - assertNotNull(outboundGroupSessionSerial); - objectInput.close(); - - // get sessions keys - String sessionKeyRef = outboundGroupSessionRef.sessionKey(); - String sessionKeySerial = outboundGroupSessionSerial.sessionKey(); - assertFalse(TextUtils.isEmpty(sessionKeyRef)); - assertFalse(TextUtils.isEmpty(sessionKeySerial)); - - // session keys comparison - assertTrue(sessionKeyRef.equals(sessionKeySerial)); - - // get sessions IDs - String sessionIdRef = outboundGroupSessionRef.sessionIdentifier(); - String sessionIdSerial = outboundGroupSessionSerial.sessionIdentifier(); - assertFalse(TextUtils.isEmpty(sessionIdRef)); - assertFalse(TextUtils.isEmpty(sessionIdSerial)); - - // session IDs comparison - assertTrue(sessionIdRef.equals(sessionIdSerial)); - - outboundGroupSessionRef.releaseSession(); - outboundGroupSessionSerial.releaseSession(); - - assertTrue(outboundGroupSessionRef.isReleased()); - assertTrue(outboundGroupSessionSerial.isReleased()); - } catch (FileNotFoundException e) { - Log.e(LOG_TAG, "## test15SerializeOutboundSession(): Exception FileNotFoundException Msg=="+e.getMessage()); - assertTrue(e.getMessage(), false); - } catch (ClassNotFoundException e) { - Log.e(LOG_TAG, "## test15SerializeOutboundSession(): Exception ClassNotFoundException Msg==" + e.getMessage()); - assertTrue(e.getMessage(), false); - } catch (OlmException e) { - Log.e(LOG_TAG, "## test15SerializeOutboundSession(): Exception OlmException Msg==" + e.getMessage()); - assertTrue(e.getMessage(), false); - } catch (IOException e) { - Log.e(LOG_TAG, "## test15SerializeOutboundSession(): Exception IOException Msg==" + e.getMessage()); - assertTrue(e.getMessage(), false); - } catch (Exception e) { - Log.e(LOG_TAG, "## test15SerializeOutboundSession(): Exception Msg==" + e.getMessage()); - assertTrue(e.getMessage(), false); - } - } - - @Test - public void test16SerializeInboundSession() { - OlmOutboundGroupSession aliceOutboundGroupSession=null; - OlmInboundGroupSession bobInboundGroupSessionRef=null; - OlmInboundGroupSession bobInboundGroupSessionSerial; - - // alice creates OUTBOUND GROUP SESSION - try { - aliceOutboundGroupSession = new OlmOutboundGroupSession(); - } catch (OlmException e) { - assertTrue("Exception in OlmOutboundGroupSession, Exception code=" + e.getExceptionCode(), false); - } - assertNotNull(aliceOutboundGroupSession); - - // get the session key from the outbound group session - String sessionKeyRef = null; - - try { - sessionKeyRef = aliceOutboundGroupSession.sessionKey(); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - assertNotNull(sessionKeyRef); - - // bob creates INBOUND GROUP SESSION - try { - bobInboundGroupSessionRef = new OlmInboundGroupSession(sessionKeyRef); - } catch (OlmException e) { - assertTrue("Exception in OlmInboundGroupSession, Exception code=" + e.getExceptionCode(), false); - } - assertNotNull(bobInboundGroupSessionRef); - - // serialize alice session - Context context = getInstrumentation().getContext(); - try { - FileOutputStream fileOutput = context.openFileOutput(FILE_NAME_SERIAL_IN_SESSION, Context.MODE_PRIVATE); - ObjectOutputStream objectOutput = new ObjectOutputStream(fileOutput); - objectOutput.writeObject(bobInboundGroupSessionRef); - objectOutput.flush(); - objectOutput.close(); - - // deserialize session - FileInputStream fileInput = context.openFileInput(FILE_NAME_SERIAL_IN_SESSION); - ObjectInputStream objectInput = new ObjectInputStream(fileInput); - bobInboundGroupSessionSerial = (OlmInboundGroupSession)objectInput.readObject(); - assertNotNull(bobInboundGroupSessionSerial); - objectInput.close(); - - // get sessions IDs - String aliceSessionId = aliceOutboundGroupSession.sessionIdentifier(); - String sessionIdRef = bobInboundGroupSessionRef.sessionIdentifier(); - String sessionIdSerial = bobInboundGroupSessionSerial.sessionIdentifier(); - assertFalse(TextUtils.isEmpty(aliceSessionId)); - assertFalse(TextUtils.isEmpty(sessionIdRef)); - assertFalse(TextUtils.isEmpty(sessionIdSerial)); - - // session IDs comparison - assertTrue(aliceSessionId.equals(sessionIdSerial)); - assertTrue(sessionIdRef.equals(sessionIdSerial)); - - aliceOutboundGroupSession.releaseSession(); - bobInboundGroupSessionRef.releaseSession(); - bobInboundGroupSessionSerial.releaseSession(); - - assertTrue(aliceOutboundGroupSession.isReleased()); - assertTrue(bobInboundGroupSessionRef.isReleased()); - assertTrue(bobInboundGroupSessionSerial.isReleased()); - } catch (FileNotFoundException e) { - Log.e(LOG_TAG, "## test16SerializeInboundSession(): Exception FileNotFoundException Msg=="+e.getMessage()); - assertTrue(e.getMessage(), false); - } catch (ClassNotFoundException e) { - Log.e(LOG_TAG, "## test16SerializeInboundSession(): Exception ClassNotFoundException Msg==" + e.getMessage()); - assertTrue(e.getMessage(), false); - } catch (OlmException e) { - Log.e(LOG_TAG, "## test16SerializeInboundSession(): Exception OlmException Msg==" + e.getMessage()); - assertTrue(e.getMessage(), false); - } catch (IOException e) { - Log.e(LOG_TAG, "## test16SerializeInboundSession(): Exception IOException Msg==" + e.getMessage()); - assertTrue(e.getMessage(), false); - } catch (Exception e) { - Log.e(LOG_TAG, "## test16SerializeInboundSession(): Exception Msg==" + e.getMessage()); - assertTrue(e.getMessage(), false); - } - } - - /** - * Create multiple outbound group sessions and check that session Keys are different. - * This test validates random series are provide enough random values. - */ - @Test - public void test17MultipleOutboundSession() { - OlmOutboundGroupSession outboundGroupSession1; - OlmOutboundGroupSession outboundGroupSession2; - OlmOutboundGroupSession outboundGroupSession3; - OlmOutboundGroupSession outboundGroupSession4; - OlmOutboundGroupSession outboundGroupSession5; - OlmOutboundGroupSession outboundGroupSession6; - OlmOutboundGroupSession outboundGroupSession7; - OlmOutboundGroupSession outboundGroupSession8; - - try { - outboundGroupSession1 = new OlmOutboundGroupSession(); - outboundGroupSession2 = new OlmOutboundGroupSession(); - outboundGroupSession3 = new OlmOutboundGroupSession(); - outboundGroupSession4 = new OlmOutboundGroupSession(); - outboundGroupSession5 = new OlmOutboundGroupSession(); - outboundGroupSession6 = new OlmOutboundGroupSession(); - outboundGroupSession7 = new OlmOutboundGroupSession(); - outboundGroupSession8 = new OlmOutboundGroupSession(); - - // get the session key from the outbound group sessions - String sessionKey1 = outboundGroupSession1.sessionKey(); - String sessionKey2 = outboundGroupSession2.sessionKey(); - assertFalse(sessionKey1.equals(sessionKey2)); - - String sessionKey3 = outboundGroupSession3.sessionKey(); - assertFalse(sessionKey2.equals(sessionKey3)); - - String sessionKey4 = outboundGroupSession4.sessionKey(); - assertFalse(sessionKey3.equals(sessionKey4)); - - String sessionKey5 = outboundGroupSession5.sessionKey(); - assertFalse(sessionKey4.equals(sessionKey5)); - - String sessionKey6 = outboundGroupSession6.sessionKey(); - assertFalse(sessionKey5.equals(sessionKey6)); - - String sessionKey7 = outboundGroupSession7.sessionKey(); - assertFalse(sessionKey6.equals(sessionKey7)); - - String sessionKey8 = outboundGroupSession8.sessionKey(); - assertFalse(sessionKey7.equals(sessionKey8)); - - // get the session IDs from the outbound group sessions - String sessionId1 = outboundGroupSession1.sessionIdentifier(); - String sessionId2 = outboundGroupSession2.sessionIdentifier(); - assertFalse(sessionId1.equals(sessionId2)); - - String sessionId3 = outboundGroupSession3.sessionKey(); - assertFalse(sessionId2.equals(sessionId3)); - - String sessionId4 = outboundGroupSession4.sessionKey(); - assertFalse(sessionId3.equals(sessionId4)); - - String sessionId5 = outboundGroupSession5.sessionKey(); - assertFalse(sessionId4.equals(sessionId5)); - - String sessionId6 = outboundGroupSession6.sessionKey(); - assertFalse(sessionId5.equals(sessionId6)); - - String sessionId7 = outboundGroupSession7.sessionKey(); - assertFalse(sessionId6.equals(sessionId7)); - - String sessionId8 = outboundGroupSession8.sessionKey(); - assertFalse(sessionId7.equals(sessionId8)); - - outboundGroupSession1.releaseSession(); - outboundGroupSession2.releaseSession(); - outboundGroupSession3.releaseSession(); - outboundGroupSession4.releaseSession(); - outboundGroupSession5.releaseSession(); - outboundGroupSession6.releaseSession(); - outboundGroupSession7.releaseSession(); - outboundGroupSession8.releaseSession(); - - assertTrue(outboundGroupSession1.isReleased()); - assertTrue(outboundGroupSession2.isReleased()); - assertTrue(outboundGroupSession3.isReleased()); - assertTrue(outboundGroupSession4.isReleased()); - assertTrue(outboundGroupSession5.isReleased()); - assertTrue(outboundGroupSession6.isReleased()); - assertTrue(outboundGroupSession7.isReleased()); - assertTrue(outboundGroupSession8.isReleased()); - } catch (OlmException e) { - assertTrue("Exception in OlmOutboundGroupSession, Exception code=" + e.getExceptionCode(), false); - } - } - - /** - * Specific test for the following run time error: - * "JNI DETECTED ERROR IN APPLICATION: input is not valid Modified UTF-8: illegal start byte 0xf0 in call to NewStringUTF".<br> - * When the msg to decrypt contain emojis, depending on the android platform, the NewStringUTF() behaves differently and - * can even crash. - * This issue is described in details here: https://github.com/eclipsesource/J2V8/issues/142 - */ - @Test - public void test18TestBadCharacterCrashInDecrypt() { - OlmInboundGroupSession bobInboundGroupSession=null; - - // values taken from a "real life" crash case - String sessionKeyRef = "AgAAAAycZE6AekIctJWYxd2AWLOY15YmxZODm/WkgbpWkyycp6ytSp/R+wo84jRrzBNWmv6ySLTZ9R0EDOk9VI2eZyQ6Efdwyo1mAvrWvTkZl9yALPdkOIVHywyG65f1SNiLrnsln3hgsT1vUrISGyKtsljoUgQpr3JDPEhD0ilAi63QBjhnGCW252b+7nF+43rb6O6lwm93LaVwe2341Gdp6EkhTUvetALezEqDOtKN00wVqAbq0RQAnUJIowxHbMswg+FyoR1K1oCjnVEoF23O9xlAn5g1XtuBZP3moJlR2lwsBA"; - String msgToDecryptWithEmoji = "AwgNEpABpjs+tYF+0y8bWtzAgYAC3N55p5cPJEEiGPU1kxIHSY7f2aG5Fj4wmcsXUkhDv0UePj922kgf+Q4dFsPHKq2aVA93n8DJAQ/FRfcM98B9E6sKCZ/PsCF78uBvF12Aaq9D3pUHBopdd7llUfVq29d5y6ZwX5VDoqV2utsATkKjXYV9CbfZuvvBMQ30ZLjEtyUUBJDY9K4FxEFcULytA/IkVnATTG9ERuLF/yB6ukSFR+iUWRYAmtuOuU0k9BvaqezbGqNoK5Grlkes+dYX6/0yUObumcw9/iAI"; - - // bob creates INBOUND GROUP SESSION - try { - bobInboundGroupSession = new OlmInboundGroupSession(sessionKeyRef); - } catch (OlmException e) { - assertTrue("Exception in test18TestBadCharacterCrashInDecrypt, Exception code=" + e.getExceptionCode(), false); - } - - OlmInboundGroupSession.DecryptMessageResult result = null; - - try { - result = bobInboundGroupSession.decryptMessage(msgToDecryptWithEmoji); - } catch (Exception e) { - assertTrue("Exception in test18TestBadCharacterCrashInDecrypt, Exception code=" + e.getMessage(), false); - } - - assertNotNull(result.mDecryptedMessage); - assertTrue(13 == result.mIndex); - } - - /** - * Specific test to check an error message is returned by decryptMessage() API.<br> - * A corrupted encrypted message is passed, and a INVALID_BASE64 is - * espexted. - **/ - @Test - public void test19TestErrorMessageReturnedInDecrypt() { - OlmInboundGroupSession bobInboundGroupSession=null; - final String EXPECTED_ERROR_MESSAGE= "INVALID_BASE64"; - - String sessionKeyRef = "AgAAAAycZE6AekIctJWYxd2AWLOY15YmxZODm/WkgbpWkyycp6ytSp/R+wo84jRrzBNWmv6ySLTZ9R0EDOk9VI2eZyQ6Efdwyo1mAvrWvTkZl9yALPdkOIVHywyG65f1SNiLrnsln3hgsT1vUrISGyKtsljoUgQpr3JDPEhD0ilAi63QBjhnGCW252b+7nF+43rb6O6lwm93LaVwe2341Gdp6EkhTUvetALezEqDOtKN00wVqAbq0RQAnUJIowxHbMswg+FyoR1K1oCjnVEoF23O9xlAn5g1XtuBZP3moJlR2lwsBA"; - String corruptedEncryptedMsg = "AwgANYTHINGf87ge45ge7gr*/rg5ganything4gr41rrgr4re55tanythingmcsXUkhDv0UePj922kgf+"; - - // valid INBOUND GROUP SESSION - try { - bobInboundGroupSession = new OlmInboundGroupSession(sessionKeyRef); - } catch (OlmException e) { - assertTrue("Exception in test19TestErrorMessageReturnedInDecrypt, Exception code=" + e.getExceptionCode(), false); - } - - String exceptionMessage = null; - try { - bobInboundGroupSession.decryptMessage(corruptedEncryptedMsg); - } catch (OlmException e) { - exceptionMessage = e.getMessage(); - } - - assertTrue(0!=EXPECTED_ERROR_MESSAGE.length()); - assertTrue(EXPECTED_ERROR_MESSAGE.equals(exceptionMessage)); - } - - - /** - * Test the import/export functions.<br> - **/ - @Test - public void test20TestInboundGroupSessionImportExport() { - - String sessionKey = "AgAAAAAwMTIzNDU2Nzg5QUJERUYwMTIzNDU2Nzg5QUJDREVGMDEyMzQ1Njc4OUFCREVGM" + - "DEyMzQ1Njc4OUFCQ0RFRjAxMjM0NTY3ODlBQkRFRjAxMjM0NTY3ODlBQkNERUYwMTIzND" + - "U2Nzg5QUJERUYwMTIzNDU2Nzg5QUJDREVGMDEyMw0bdg1BDq4Px/slBow06q8n/B9WBfw" + - "WYyNOB8DlUmXGGwrFmaSb9bR/eY8xgERrxmP07hFmD9uqA2p8PMHdnV5ysmgufE6oLZ5+" + - "8/mWQOW3VVTnDIlnwd8oHUYRuk8TCQ"; - - String message = "AwgAEhAcbh6UpbByoyZxufQ+h2B+8XHMjhR69G8F4+qjMaFlnIXusJZX3r8LnRORG9T3D" + - "XFdbVuvIWrLyRfm4i8QRbe8VPwGRFG57B1CtmxanuP8bHtnnYqlwPsD"; - - - OlmInboundGroupSession inboundGroupSession = null; - - try { - inboundGroupSession = new OlmInboundGroupSession(sessionKey); - } catch (Exception e) { - assertTrue("OlmInboundGroupSession failed " + e.getMessage(), false); - } - - boolean isVerified = false; - - try { - isVerified = inboundGroupSession.isVerified(); - } catch (Exception e) { - assertTrue("isVerified failed " + e.getMessage(), false); - } - - assertTrue(isVerified); - - OlmInboundGroupSession.DecryptMessageResult result = null; - - try { - result = inboundGroupSession.decryptMessage(message); - } catch (Exception e) { - assertTrue("decryptMessage failed " + e.getMessage(), false); - } - - assertTrue(TextUtils.equals(result.mDecryptedMessage, "Message")); - assertTrue(0 == result.mIndex); - - String export = null; - - try { - export = inboundGroupSession.export(0); - } catch (Exception e) { - assertTrue("export failed " + e.getMessage(), false); - } - assertTrue(!TextUtils.isEmpty(export)); - - long index = -1; - try { - index = inboundGroupSession.getFirstKnownIndex(); - } catch (Exception e) { - assertTrue("getFirstKnownIndex failed " + e.getMessage(), false); - } - assertTrue(index >=0); - - inboundGroupSession.releaseSession(); - inboundGroupSession = null; - - OlmInboundGroupSession inboundGroupSession2 = null; - - try { - inboundGroupSession2 = inboundGroupSession.importSession(export); - } catch (Exception e) { - assertTrue("OlmInboundGroupSession failed " + e.getMessage(), false); - } - - try { - isVerified = inboundGroupSession2.isVerified(); - } catch (Exception e) { - assertTrue("isVerified failed " + e.getMessage(), false); - } - - assertFalse(isVerified); - - result = null; - try { - result = inboundGroupSession2.decryptMessage(message); - } catch (Exception e) { - assertTrue("decryptMessage failed " + e.getMessage(), false); - } - - assertTrue(TextUtils.equals(result.mDecryptedMessage, "Message")); - assertTrue(0 == result.mIndex); - - try { - isVerified = inboundGroupSession2.isVerified(); - } catch (Exception e) { - assertTrue("isVerified failed " + e.getMessage(), false); - } - - assertTrue(isVerified); - inboundGroupSession2.releaseSession(); - } -} - diff --git a/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmPkTest.java b/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmPkTest.java deleted file mode 100644 index d1e4a2e..0000000 --- a/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmPkTest.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * 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. - */ - -package org.matrix.olm; - -import android.support.test.runner.AndroidJUnit4; -import android.util.Log; - -import java.util.Arrays; - -import org.junit.BeforeClass; -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -@RunWith(AndroidJUnit4.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class OlmPkTest { - private static final String LOG_TAG = "OlmPkEncryptionTest"; - - private static OlmPkEncryption mOlmPkEncryption; - private static OlmPkDecryption mOlmPkDecryption; - private static OlmPkSigning mOlmPkSigning; - - @Test - public void test01EncryptAndDecrypt() { - try { - mOlmPkEncryption = new OlmPkEncryption(); - } catch (OlmException e) { - e.printStackTrace(); - assertTrue("OlmPkEncryption failed " + e.getMessage(), false); - } - try { - mOlmPkDecryption = new OlmPkDecryption(); - } catch (OlmException e) { - e.printStackTrace(); - assertTrue("OlmPkEncryption failed " + e.getMessage(), false); - } - - assertNotNull(mOlmPkEncryption); - assertNotNull(mOlmPkDecryption); - - String key = null; - try { - key = mOlmPkDecryption.generateKey(); - } catch (OlmException e) { - assertTrue("Exception in generateKey, Exception code=" + e.getExceptionCode(), false); - } - Log.d(LOG_TAG, "Ephemeral Key: " + key); - try { - mOlmPkEncryption.setRecipientKey(key); - } catch (OlmException e) { - assertTrue("Exception in setRecipientKey, Exception code=" + e.getExceptionCode(), false); - } - - String clearMessage = "Public key test"; - OlmPkMessage message = null; - try { - message = mOlmPkEncryption.encrypt(clearMessage); - } catch (OlmException e) { - assertTrue("Exception in encrypt, Exception code=" + e.getExceptionCode(), false); - } - Log.d(LOG_TAG, "message: " + message.mCipherText + " " + message.mMac + " " + message.mEphemeralKey); - - String decryptedMessage = null; - try { - decryptedMessage = mOlmPkDecryption.decrypt(message); - } catch (OlmException e) { - assertTrue("Exception in decrypt, Exception code=" + e.getExceptionCode(), false); - } - assertTrue(clearMessage.equals(decryptedMessage)); - - mOlmPkEncryption.releaseEncryption(); - mOlmPkDecryption.releaseDecryption(); - assertTrue(mOlmPkEncryption.isReleased()); - assertTrue(mOlmPkDecryption.isReleased()); - } - - @Test - public void test02PrivateKey() { - try { - mOlmPkDecryption = new OlmPkDecryption(); - } catch (OlmException e) { - e.printStackTrace(); - assertTrue("OlmPkEncryption failed " + e.getMessage(), false); - } - - assertNotNull(mOlmPkDecryption); - - byte[] privateKey = { - (byte)0x77, (byte)0x07, (byte)0x6D, (byte)0x0A, - (byte)0x73, (byte)0x18, (byte)0xA5, (byte)0x7D, - (byte)0x3C, (byte)0x16, (byte)0xC1, (byte)0x72, - (byte)0x51, (byte)0xB2, (byte)0x66, (byte)0x45, - (byte)0xDF, (byte)0x4C, (byte)0x2F, (byte)0x87, - (byte)0xEB, (byte)0xC0, (byte)0x99, (byte)0x2A, - (byte)0xB1, (byte)0x77, (byte)0xFB, (byte)0xA5, - (byte)0x1D, (byte)0xB9, (byte)0x2C, (byte)0x2A - }; - - assertTrue(privateKey.length == OlmPkDecryption.privateKeyLength()); - - try { - mOlmPkDecryption.setPrivateKey(privateKey); - } catch (OlmException e) { - assertTrue("Exception in setPrivateKey, Exception code=" + e.getExceptionCode(), false); - } - - byte[] privateKeyCopy = null; - - try { - privateKeyCopy = mOlmPkDecryption.privateKey(); - } catch (OlmException e) { - assertTrue("Exception in privateKey, Exception code=" + e.getExceptionCode(), false); - } - - assertTrue(Arrays.equals(privateKey, privateKeyCopy)); - - mOlmPkDecryption.releaseDecryption(); - assertTrue(mOlmPkDecryption.isReleased()); - } - - @Test - public void test03Signing() { - try { - mOlmPkSigning = new OlmPkSigning(); - } catch (OlmException e) { - e.printStackTrace(); - assertTrue("OlmPkSigning failed " + e.getMessage(), false); - } - - assertNotNull(mOlmPkSigning); - - byte[] seed = null; - try { - seed = OlmPkSigning.generateSeed(); - } catch (OlmException e) { - e.printStackTrace(); - assertTrue("generateSeed failed " + e.getMessage(), false); - } - - assertTrue(seed.length == OlmPkSigning.seedLength()); - - String pubkey = null; - try { - pubkey = mOlmPkSigning.initWithSeed(seed); - } catch (OlmException e) { - e.printStackTrace(); - 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 signature = null; - try { - signature = mOlmPkSigning.sign(message); - } catch (OlmException e) { - e.printStackTrace(); - assertTrue("sign failed " + e.getMessage(), false); - } - - OlmUtility olmUtility = null; - try { - olmUtility = new OlmUtility(); - } catch (OlmException e) { - e.printStackTrace(); - assertTrue("olmUtility failed " + e.getMessage(), false); - } - - try { - olmUtility.verifyEd25519Signature(signature, pubkey, message); - } catch (OlmException e) { - e.printStackTrace(); - assertTrue("Signature verification failed " + e.getMessage(), false); - } - - mOlmPkSigning.releaseSigning(); - assertTrue(mOlmPkSigning.isReleased()); - - olmUtility.releaseUtility(); - } -} diff --git a/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSasTest.java b/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSasTest.java deleted file mode 100644 index bbb50ae..0000000 --- a/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSasTest.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 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. - */ - -package org.matrix.olm; - - -import android.support.test.runner.AndroidJUnit4; -import android.util.Log; - -import org.junit.BeforeClass; -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -@RunWith(AndroidJUnit4.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class OlmSasTest { - - private static OlmManager mOlmManager; - - //Enable the native lib - @BeforeClass - public static void setUpClass() { - // load native librandomBytesOfLength - mOlmManager = new OlmManager(); - } - - @Test - public void testSASCode() { - OlmSAS aliceSas = null; - OlmSAS bobSas = null; - - try { - aliceSas = new OlmSAS(); - bobSas = new OlmSAS(); - - String alicePKey = aliceSas.getPublicKey(); - String bobPKey = bobSas.getPublicKey(); - - Log.e(OlmSasTest.class.getSimpleName(), "#### Alice pub Key is " + alicePKey); - Log.e(OlmSasTest.class.getSimpleName(), "#### Bob pub Key is " + bobPKey); - - aliceSas.setTheirPublicKey(bobPKey); - bobSas.setTheirPublicKey(alicePKey); - - int codeLength = 6; - byte[] alice_sas = aliceSas.generateShortCode("SAS", codeLength); - byte[] bob_sas = bobSas.generateShortCode("SAS", codeLength); - - Log.e(OlmSasTest.class.getSimpleName(), "#### Alice SAS is " + new String(alice_sas, "UTF-8")); - Log.e(OlmSasTest.class.getSimpleName(), "#### Bob SAS is " + new String(bob_sas, "UTF-8")); - - assertEquals(codeLength, alice_sas.length); - assertEquals(codeLength, bob_sas.length); - assertArrayEquals(alice_sas, bob_sas); - - String aliceMac = aliceSas.calculateMac("Hello world!", "SAS"); - String bobMac = bobSas.calculateMac("Hello world!", "SAS"); - - assertEquals(aliceMac, bobMac); - - Log.e(OlmSasTest.class.getSimpleName(), "#### Alice Mac is " + aliceMac); - Log.e(OlmSasTest.class.getSimpleName(), "#### Bob Mac is " + bobMac); - - - String aliceLongKdfMac = aliceSas.calculateMacLongKdf("Hello world!", "SAS"); - String bobLongKdfMac = bobSas.calculateMacLongKdf("Hello world!", "SAS"); - - assertEquals("Mac should be the same", aliceLongKdfMac, bobLongKdfMac); - - Log.e(OlmSasTest.class.getSimpleName(), "#### Alice lkdf Mac is " + aliceLongKdfMac); - Log.e(OlmSasTest.class.getSimpleName(), "#### Bob lkdf Mac is " + bobLongKdfMac); - - - } catch (Exception e) { - assertTrue("OlmSas init failed " + e.getMessage(), false); - e.printStackTrace(); - } finally { - if (aliceSas != null) { - aliceSas.releaseSas(); - } - if (bobSas != null) { - bobSas.releaseSas(); - } - } - } - -} diff --git a/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java b/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java deleted file mode 100644 index e08b151..0000000 --- a/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java +++ /dev/null @@ -1,1014 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016 Vector Creations 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. - */ - -package org.matrix.olm; - -import android.content.Context; -import android.support.test.runner.AndroidJUnit4; -import android.text.TextUtils; -import android.util.Log; - -import org.json.JSONObject; -import org.junit.BeforeClass; -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.Map; - -import static android.support.test.InstrumentationRegistry.getInstrumentation; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -@RunWith(AndroidJUnit4.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class OlmSessionTest { - private static final String LOG_TAG = "OlmSessionTest"; - private final String INVALID_PRE_KEY = "invalid PRE KEY hu hu!"; - private final String FILE_NAME_SERIAL_SESSION = "SerialSession"; - private final int ONE_TIME_KEYS_NUMBER = 4; - - private static OlmManager mOlmManager; - - @BeforeClass - public static void setUpClass(){ - // load native lib - mOlmManager = new OlmManager(); - - String version = mOlmManager.getOlmLibVersion(); - assertNotNull(version); - Log.d(LOG_TAG, "## setUpClass(): lib version="+version); - } - - /** - * Basic test: - * - alice creates an account - * - bob creates an account - * - alice creates an outbound session with bob (bobIdentityKey & bobOneTimeKey) - * - alice encrypts a message with its session - * - bob creates an inbound session based on alice's encrypted message - * - bob decrypts the encrypted message with its session - */ - @Test - public void test01AliceToBob() { - final int ONE_TIME_KEYS_NUMBER = 5; - String bobIdentityKey = null; - String bobOneTimeKey=null; - OlmAccount bobAccount = null; - OlmAccount aliceAccount = null; - - // ALICE & BOB ACCOUNTS CREATION - try { - aliceAccount = new OlmAccount(); - bobAccount = new OlmAccount(); - } catch (OlmException e) { - assertTrue(e.getMessage(),false); - } - - // test accounts creation - assertTrue(0!=bobAccount.getOlmAccountId()); - assertTrue(0!=aliceAccount.getOlmAccountId()); - - // get bob identity key - Map<String, String> bobIdentityKeys = null; - - try { - bobIdentityKeys = bobAccount.identityKeys(); - } catch (Exception e) { - assertTrue("identityKeys failed " + e.getMessage(), false); - } - - bobIdentityKey = TestHelper.getIdentityKey(bobIdentityKeys); - assertTrue(null!=bobIdentityKey); - - // get bob one time keys - try { - bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - Map<String, Map<String, String>> bobOneTimeKeys = null; - - try { - bobOneTimeKeys = bobAccount.oneTimeKeys(); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - bobOneTimeKey = TestHelper.getOneTimeKey(bobOneTimeKeys,1); - assertNotNull(bobOneTimeKey); - - // CREATE ALICE SESSION - OlmSession aliceSession = null; - try { - aliceSession = new OlmSession(); - } catch (OlmException e) { - assertTrue("Exception Msg="+e.getMessage(), false); - } - assertTrue(0!=aliceSession.getOlmSessionId()); - - // CREATE ALICE OUTBOUND SESSION and encrypt message to bob - try { - aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - String clearMsg = "Heloo bob , this is alice!"; - OlmMessage encryptedMsgToBob = null; - try { - encryptedMsgToBob = aliceSession.encryptMessage(clearMsg); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - assertNotNull(encryptedMsgToBob); - assertNotNull(encryptedMsgToBob.mCipherText); - Log.d(LOG_TAG,"## test01AliceToBob(): encryptedMsg="+encryptedMsgToBob.mCipherText); - - // CREATE BOB INBOUND SESSION and decrypt message from alice - OlmSession bobSession = null; - try { - bobSession = new OlmSession(); - } catch (OlmException e) { - assertTrue("Exception Msg="+e.getMessage(), false); - } - assertTrue(0!=bobSession.getOlmSessionId()); - - try { - bobSession.initInboundSession(bobAccount, encryptedMsgToBob.mCipherText); - } catch (Exception e) { - assertTrue("initInboundSessionWithAccount failed " + e.getMessage(), false); - } - - String decryptedMsg = null; - try { - decryptedMsg = bobSession.decryptMessage(encryptedMsgToBob); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - assertNotNull(decryptedMsg); - - // MESSAGE COMPARISON: decrypted vs encrypted - assertTrue(clearMsg.equals(decryptedMsg)); - - // clean objects.. - try { - bobAccount.removeOneTimeKeys(bobSession); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - // release accounts - bobAccount.releaseAccount(); - aliceAccount.releaseAccount(); - assertTrue(bobAccount.isReleased()); - assertTrue(aliceAccount.isReleased()); - - // release sessions - bobSession.releaseSession(); - aliceSession.releaseSession(); - assertTrue(bobSession.isReleased()); - assertTrue(aliceSession.isReleased()); - } - - - /** - * Same as test01AliceToBob but with bob who's encrypting messages - * to alice and alice decrypt them.<br> - * - alice creates an account - * - bob creates an account - * - alice creates an outbound session with bob (bobIdentityKey & bobOneTimeKey) - * - alice encrypts a message with its own session - * - bob creates an inbound session based on alice's encrypted message - * - bob decrypts the encrypted message with its own session - * - bob encrypts messages with its own session - * - alice decrypts bob's messages with its own message - * - alice encrypts a message - * - bob decrypts the encrypted message - */ - @Test - public void test02AliceToBobBackAndForth() { - String bobIdentityKey; - String bobOneTimeKey; - OlmAccount aliceAccount = null; - OlmAccount bobAccount = null; - - // creates alice & bob accounts - try { - aliceAccount = new OlmAccount(); - bobAccount = new OlmAccount(); - } catch (OlmException e) { - assertTrue(e.getMessage(),false); - } - - // test accounts creation - assertTrue(0!=bobAccount.getOlmAccountId()); - assertTrue(0!=aliceAccount.getOlmAccountId()); - - // get bob identity key - Map<String, String> bobIdentityKeys = null; - - try { - bobIdentityKeys = bobAccount.identityKeys(); - } catch (Exception e) { - assertTrue("identityKeys failed " + e.getMessage(), false); - } - - bobIdentityKey = TestHelper.getIdentityKey(bobIdentityKeys); - assertTrue(null!=bobIdentityKey); - - // get bob one time keys - try { - bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - Map<String, Map<String, String>> bobOneTimeKeys = null; - - try { - bobOneTimeKeys = bobAccount.oneTimeKeys(); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - bobOneTimeKey = TestHelper.getOneTimeKey(bobOneTimeKeys,1); - assertNotNull(bobOneTimeKey); - - // CREATE ALICE SESSION - OlmSession aliceSession = null; - try { - aliceSession = new OlmSession(); - } catch (OlmException e) { - assertTrue("Exception Msg="+e.getMessage(), false); - } - assertTrue(0!=aliceSession.getOlmSessionId()); - - // CREATE ALICE OUTBOUND SESSION and encrypt message to bob - try { - aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - String helloClearMsg = "Hello I'm Alice!"; - - OlmMessage encryptedAliceToBobMsg1 = null; - - try { - encryptedAliceToBobMsg1 = aliceSession.encryptMessage(helloClearMsg); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - assertNotNull(encryptedAliceToBobMsg1); - assertNotNull(encryptedAliceToBobMsg1.mCipherText); - - // CREATE BOB INBOUND SESSION and decrypt message from alice - OlmSession bobSession = null; - try { - bobSession = new OlmSession(); - } catch (OlmException e) { - assertTrue("Exception Msg="+e.getMessage(), false); - } - - assertTrue(0!=bobSession.getOlmSessionId()); - - try { - bobSession.initInboundSession(bobAccount, encryptedAliceToBobMsg1.mCipherText); - } catch (Exception e) { - assertTrue("initInboundSessionWithAccount failed " + e.getMessage(), false); - } - - // DECRYPT MESSAGE FROM ALICE - String decryptedMsg01 = null; - try { - decryptedMsg01 = bobSession.decryptMessage(encryptedAliceToBobMsg1); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - assertNotNull(decryptedMsg01); - - // MESSAGE COMPARISON: decrypted vs encrypted - assertTrue(helloClearMsg.equals(decryptedMsg01)); - - // BACK/FORTH MESSAGE COMPARISON - String clearMsg1 = "Hello I'm Bob!"; - String clearMsg2 = "Isn't life grand?"; - String clearMsg3 = "Let's go to the opera."; - - // bob encrypts messages - OlmMessage encryptedMsg1 = null; - try { - encryptedMsg1 = bobSession.encryptMessage(clearMsg1); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - assertNotNull(encryptedMsg1); - - OlmMessage encryptedMsg2 = null; - try { - encryptedMsg2 = bobSession.encryptMessage(clearMsg2); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - assertNotNull(encryptedMsg2); - - - OlmMessage encryptedMsg3 = null; - try { - encryptedMsg3 = bobSession.encryptMessage(clearMsg3); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - assertNotNull(encryptedMsg3); - - // alice decrypts bob's messages - String decryptedMsg1 = null; - try { - decryptedMsg1 = aliceSession.decryptMessage(encryptedMsg1); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - assertNotNull(decryptedMsg1); - String decryptedMsg2 = null; - try { - decryptedMsg2 = aliceSession.decryptMessage(encryptedMsg2); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - assertNotNull(decryptedMsg2); - String decryptedMsg3 = null; - try { - decryptedMsg3 = aliceSession.decryptMessage(encryptedMsg3); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - assertNotNull(decryptedMsg3); - - // comparison tests - assertTrue(clearMsg1.equals(decryptedMsg1)); - assertTrue(clearMsg2.equals(decryptedMsg2)); - assertTrue(clearMsg3.equals(decryptedMsg3)); - - // and one more from alice to bob - clearMsg1 = "another message from Alice to Bob!!"; - encryptedMsg1 = null; - - try { - encryptedMsg1 = aliceSession.encryptMessage(clearMsg1); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - assertNotNull(encryptedMsg1); - - decryptedMsg1 = null; - try { - decryptedMsg1 = bobSession.decryptMessage(encryptedMsg1); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - assertNotNull(decryptedMsg1); - assertTrue(clearMsg1.equals(decryptedMsg1)); - - // comparison test - assertTrue(clearMsg1.equals(decryptedMsg1)); - - // clean objects.. - try { - bobAccount.removeOneTimeKeys(bobSession); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - bobAccount.releaseAccount(); - aliceAccount.releaseAccount(); - assertTrue(bobAccount.isReleased()); - assertTrue(aliceAccount.isReleased()); - - bobSession.releaseSession(); - aliceSession.releaseSession(); - assertTrue(bobSession.isReleased()); - assertTrue(aliceSession.isReleased()); - } - - - @Test - public void test03AliceBobSessionId() { - // creates alice & bob accounts - OlmAccount aliceAccount = null; - OlmAccount bobAccount = null; - try { - aliceAccount = new OlmAccount(); - bobAccount = new OlmAccount(); - } catch (OlmException e) { - assertTrue(e.getMessage(),false); - } - - // test accounts creation - assertTrue(0!=bobAccount.getOlmAccountId()); - assertTrue(0!=aliceAccount.getOlmAccountId()); - - // CREATE ALICE SESSION - - OlmSession aliceSession = null; - try { - aliceSession = new OlmSession(); - } catch (OlmException e) { - assertTrue("Exception Msg="+e.getMessage(), false); - } - assertTrue(0!=aliceSession.getOlmSessionId()); - - // CREATE ALICE SESSION - OlmSession bobSession = null; - try { - bobSession = new OlmSession(); - } catch (OlmException e) { - e.printStackTrace(); - assertTrue(e.getMessage(), false); - } - assertTrue(0!=bobSession.getOlmSessionId()); - - String aliceSessionId = null; - try { - aliceSessionId = aliceSession.sessionIdentifier(); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - assertNotNull(aliceSessionId); - - String bobSessionId = null; - try { - bobSessionId = bobSession.sessionIdentifier(); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - assertNotNull(bobSessionId); - - // must be the same for both ends of the conversation - assertTrue(aliceSessionId.equals(bobSessionId)); - - aliceAccount.releaseAccount(); - bobAccount.releaseAccount(); - assertTrue(aliceAccount.isReleased()); - assertTrue(bobAccount.isReleased()); - - bobSession.releaseSession(); - aliceSession.releaseSession(); - assertTrue(bobSession.isReleased()); - assertTrue(aliceSession.isReleased()); - } - - @Test - public void test04MatchInboundSession() { - OlmAccount aliceAccount=null, bobAccount=null; - OlmSession aliceSession = null, bobSession = null; - - // ACCOUNTS CREATION - try { - aliceAccount = new OlmAccount(); - bobAccount = new OlmAccount(); - } catch (OlmException e) { - assertTrue(e.getMessage(), false); - } - - // CREATE ALICE SESSION - try { - aliceSession = new OlmSession(); - bobSession = new OlmSession(); - } catch (OlmException e) { - assertTrue("Exception Msg=" + e.getMessage(), false); - } - - // get bob/luke identity key - Map<String, String> bobIdentityKeys = null; - - try { - bobIdentityKeys = bobAccount.identityKeys(); - } catch (Exception e) { - assertTrue("identityKeys failed " + e.getMessage(), false); - } - - Map<String, String> aliceIdentityKeys = null; - - try { - aliceIdentityKeys = aliceAccount.identityKeys(); - } catch (Exception e) { - assertTrue("identityKeys failed " + e.getMessage(), false); - } - - String bobIdentityKey = TestHelper.getIdentityKey(bobIdentityKeys); - String aliceIdentityKey = TestHelper.getIdentityKey(aliceIdentityKeys); - - // get bob/luke one time keys - try { - bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - try { - aliceAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - Map<String, Map<String, String>> bobOneTimeKeys = null; - - try { - bobOneTimeKeys = bobAccount.oneTimeKeys(); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - String bobOneTimeKey1 = TestHelper.getOneTimeKey(bobOneTimeKeys, 1); - - // create alice inbound session for bob - try { - aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey1); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - String aliceClearMsg = "hello helooo to bob!"; - OlmMessage encryptedAliceToBobMsg1 = null; - - try { - encryptedAliceToBobMsg1 = aliceSession.encryptMessage(aliceClearMsg); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - assertFalse(bobSession.matchesInboundSession(encryptedAliceToBobMsg1.mCipherText)); - - // init bob session with alice PRE KEY - try { - bobSession.initInboundSession(bobAccount, encryptedAliceToBobMsg1.mCipherText); - } catch (Exception e) { - assertTrue("initInboundSessionWithAccount failed " + e.getMessage(), false); - } - - // test matchesInboundSession() and matchesInboundSessionFrom() - assertTrue(bobSession.matchesInboundSession(encryptedAliceToBobMsg1.mCipherText)); - assertTrue(bobSession.matchesInboundSessionFrom(aliceIdentityKey, encryptedAliceToBobMsg1.mCipherText)); - // following requires olm native lib new version with https://github.com/matrix-org/olm-backup/commit/7e9f3bebb8390f975a76c0188ce4cb460fe6692e - //assertTrue(false==bobSession.matchesInboundSessionFrom(bobIdentityKey, encryptedAliceToBobMsg1.mCipherText)); - - // release objects - try { - bobAccount.removeOneTimeKeys(bobSession); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - aliceAccount.releaseAccount(); - bobAccount.releaseAccount(); - assertTrue(aliceAccount.isReleased()); - assertTrue(bobAccount.isReleased()); - - aliceSession.releaseSession(); - bobSession.releaseSession(); - assertTrue(aliceSession.isReleased()); - assertTrue(bobSession.isReleased()); - } - - // ******************************************************** - // ************* SERIALIZATION TEST *********************** - // ******************************************************** - /** - * Same as {@link #test02AliceToBobBackAndForth()}, but alice's session - * is serialized and de-serialized before performing the final - * comparison (encrypt vs ) - */ - @Test - public void test05SessionSerialization() { - final int ONE_TIME_KEYS_NUMBER = 1; - String bobIdentityKey; - String bobOneTimeKey; - OlmAccount aliceAccount = null; - OlmAccount bobAccount = null; - OlmSession aliceSessionDeserial = null; - - // creates alice & bob accounts - try { - aliceAccount = new OlmAccount(); - bobAccount = new OlmAccount(); - } catch (OlmException e) { - assertTrue(e.getMessage(),false); - } - - // test accounts creation - assertTrue(0!=bobAccount.getOlmAccountId()); - assertTrue(0!=aliceAccount.getOlmAccountId()); - - // get bob identity key - Map<String, String> bobIdentityKeys = null; - - try { - bobIdentityKeys = bobAccount.identityKeys(); - } catch (Exception e) { - assertTrue("identityKeys failed " + e.getMessage(), false); - } - - bobIdentityKey = TestHelper.getIdentityKey(bobIdentityKeys); - assertTrue(null!=bobIdentityKey); - - // get bob one time keys - try { - bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - Map<String, Map<String, String>> bobOneTimeKeys = null; - - try { - bobOneTimeKeys = bobAccount.oneTimeKeys(); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - bobOneTimeKey = TestHelper.getOneTimeKey(bobOneTimeKeys,1); - assertNotNull(bobOneTimeKey); - - // CREATE ALICE SESSION - OlmSession aliceSession = null; - try { - aliceSession = new OlmSession(); - } catch (OlmException e) { - assertTrue("Exception Msg="+e.getMessage(), false); - } - assertTrue(0!=aliceSession.getOlmSessionId()); - - // CREATE ALICE OUTBOUND SESSION and encrypt message to bob - try { - aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - String helloClearMsg = "Hello I'm Alice!"; - - OlmMessage encryptedAliceToBobMsg1 = null; - try { - encryptedAliceToBobMsg1 = aliceSession.encryptMessage(helloClearMsg); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - assertNotNull(encryptedAliceToBobMsg1); - assertNotNull(encryptedAliceToBobMsg1.mCipherText); - - // CREATE BOB INBOUND SESSION and decrypt message from alice - OlmSession bobSession = null; - try { - bobSession = new OlmSession(); - } catch (OlmException e) { - assertTrue("Exception Msg="+e.getMessage(), false); - } - assertTrue(0!=bobSession.getOlmSessionId()); - - // init bob session with alice PRE KEY - try { - bobSession.initInboundSession(bobAccount, encryptedAliceToBobMsg1.mCipherText); - } catch (Exception e) { - assertTrue("initInboundSessionWithAccount failed " + e.getMessage(), false); - } - - // DECRYPT MESSAGE FROM ALICE - String decryptedMsg01 = null; - - try { - decryptedMsg01 = bobSession.decryptMessage(encryptedAliceToBobMsg1); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - assertNotNull(decryptedMsg01); - - // MESSAGE COMPARISON: decrypted vs encrypted - assertTrue(helloClearMsg.equals(decryptedMsg01)); - - // BACK/FORTH MESSAGE COMPARISON - String clearMsg1 = "Hello I'm Bob!"; - String clearMsg2 = "Isn't life grand?"; - String clearMsg3 = "Let's go to the opera."; - - // bob encrypts messages - OlmMessage encryptedMsg1 = null; - try { - encryptedMsg1 = bobSession.encryptMessage(clearMsg1); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - assertNotNull(encryptedMsg1); - - OlmMessage encryptedMsg2 = null; - try { - encryptedMsg2 = bobSession.encryptMessage(clearMsg2); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - assertNotNull(encryptedMsg2); - - OlmMessage encryptedMsg3 = null; - try { - encryptedMsg3 = bobSession.encryptMessage(clearMsg3); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - assertNotNull(encryptedMsg3); - - // serialize alice session - Context context = getInstrumentation().getContext(); - try { - FileOutputStream fileOutput = context.openFileOutput(FILE_NAME_SERIAL_SESSION, Context.MODE_PRIVATE); - ObjectOutputStream objectOutput = new ObjectOutputStream(fileOutput); - objectOutput.writeObject(aliceSession); - objectOutput.flush(); - objectOutput.close(); - - // deserialize session - FileInputStream fileInput = context.openFileInput(FILE_NAME_SERIAL_SESSION); - ObjectInputStream objectInput = new ObjectInputStream(fileInput); - aliceSessionDeserial = (OlmSession) objectInput.readObject(); - objectInput.close(); - - // test deserialize return value - assertNotNull(aliceSessionDeserial); - - // de-serialized alice session decrypts bob's messages - String decryptedMsg1 = aliceSessionDeserial.decryptMessage(encryptedMsg1); - assertNotNull(decryptedMsg1); - String decryptedMsg2 = aliceSessionDeserial.decryptMessage(encryptedMsg2); - assertNotNull(decryptedMsg2); - String decryptedMsg3 = aliceSessionDeserial.decryptMessage(encryptedMsg3); - assertNotNull(decryptedMsg3); - - // comparison tests - assertTrue(clearMsg1.equals(decryptedMsg1)); - assertTrue(clearMsg2.equals(decryptedMsg2)); - assertTrue(clearMsg3.equals(decryptedMsg3)); - - // clean objects.. - try { - bobAccount.removeOneTimeKeys(bobSession); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - bobAccount.releaseAccount(); - aliceAccount.releaseAccount(); - assertTrue(bobAccount.isReleased()); - assertTrue(aliceAccount.isReleased()); - - bobSession.releaseSession(); - aliceSession.releaseSession(); - aliceSessionDeserial.releaseSession(); - assertTrue(bobSession.isReleased()); - assertTrue(aliceSession.isReleased()); - assertTrue(aliceSessionDeserial.isReleased()); - } - catch (FileNotFoundException e) { - Log.e(LOG_TAG, "## test03SessionSerialization(): Exception FileNotFoundException Msg=="+e.getMessage()); - assertTrue(e.getMessage(), false); - } - catch (ClassNotFoundException e) { - Log.e(LOG_TAG, "## test03SessionSerialization(): Exception ClassNotFoundException Msg==" + e.getMessage()); - assertTrue(e.getMessage(), false); - } - catch (IOException e) { - Log.e(LOG_TAG, "## test03SessionSerialization(): Exception IOException Msg==" + e.getMessage()); - assertTrue(e.getMessage(), false); - } - /*catch (OlmException e) { - Log.e(LOG_TAG, "## test03SessionSerialization(): Exception OlmException Msg==" + e.getMessage()); - }*/ - catch (Exception e) { - Log.e(LOG_TAG, "## test03SessionSerialization(): Exception Msg==" + e.getMessage()); - assertTrue(e.getMessage(), false); - } - } - - - // **************************************************** - // *************** SANITY CHECK TESTS ***************** - // **************************************************** - - @Test - public void test06SanityCheckErrors() { - final int ONE_TIME_KEYS_NUMBER = 5; - OlmAccount bobAccount = null; - OlmAccount aliceAccount = null; - - // ALICE & BOB ACCOUNTS CREATION - try { - aliceAccount = new OlmAccount(); - bobAccount = new OlmAccount(); - } catch (OlmException e) { - assertTrue(e.getMessage(), false); - } - - // get bob identity key - Map<String, String> bobIdentityKeys = null; - - try { - bobIdentityKeys = bobAccount.identityKeys(); - } catch (Exception e) { - assertTrue("identityKeys failed " + e.getMessage(), false); - } - - String bobIdentityKey = TestHelper.getIdentityKey(bobIdentityKeys); - assertTrue(null != bobIdentityKey); - - // get bob one time keys - try { - bobAccount.generateOneTimeKeys(ONE_TIME_KEYS_NUMBER); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - Map<String, Map<String, String>> bobOneTimeKeys = null; - - try { - bobOneTimeKeys = bobAccount.oneTimeKeys(); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - assertNotNull(bobOneTimeKeys); - String bobOneTimeKey = TestHelper.getOneTimeKey(bobOneTimeKeys,1); - assertNotNull(bobOneTimeKey); - - // CREATE ALICE SESSION - OlmSession aliceSession = null; - try { - aliceSession = new OlmSession(); - } catch (OlmException e) { - assertTrue("Exception Msg=" + e.getMessage(), false); - } - - // SANITY CHECK TESTS FOR: initOutboundSessionWithAccount() - String errorMessage = null; - try { - aliceSession.initOutboundSession(null, bobIdentityKey, bobOneTimeKey); - } catch (Exception e) { - errorMessage = e.getMessage(); - } - assertTrue(null != errorMessage); - - errorMessage = null; - try { - aliceSession.initOutboundSession(aliceAccount, null, bobOneTimeKey); - } catch (Exception e) { - errorMessage = e.getMessage(); - } - assertTrue(null != errorMessage); - - errorMessage = null; - try { - aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, null); - } catch (Exception e) { - errorMessage = e.getMessage(); - } - assertTrue(null != errorMessage); - - errorMessage = null; - try { - aliceSession.initOutboundSession(null, null, null); - } catch (Exception e) { - errorMessage = e.getMessage(); - } - assertTrue(null != errorMessage); - - // init properly - errorMessage = null; - try { - aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey); - } catch (Exception e) { - errorMessage = e.getMessage(); - } - assertTrue(null == errorMessage); - - // SANITY CHECK TESTS FOR: encryptMessage() - OlmMessage message = null; - try { - message = aliceSession.encryptMessage(null); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - assertTrue(null==message); - - // encrypt properly - OlmMessage encryptedMsgToBob = null; - try { - encryptedMsgToBob = aliceSession.encryptMessage("A message for bob"); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - assertNotNull(encryptedMsgToBob); - - // SANITY CHECK TESTS FOR: initInboundSessionWithAccount() - OlmSession bobSession = null; - try { - bobSession = new OlmSession(); - errorMessage = null; - try { - bobSession.initInboundSession(null, encryptedMsgToBob.mCipherText); - } catch (Exception e) { - errorMessage = e.getMessage(); - } - - assertTrue(!TextUtils.isEmpty(errorMessage)); - - errorMessage = null; - try { - bobSession.initInboundSession(bobAccount, null); - } catch (Exception e) { - errorMessage = e.getMessage(); - } - - assertTrue(!TextUtils.isEmpty(errorMessage)); - - errorMessage = null; - try { - bobSession.initInboundSession(bobAccount, INVALID_PRE_KEY); - } catch (Exception e) { - errorMessage = e.getMessage(); - } - - assertTrue(!TextUtils.isEmpty(errorMessage)); - - // init properly - errorMessage = null; - try { - bobSession.initInboundSession(bobAccount, encryptedMsgToBob.mCipherText); - } catch (Exception e) { - errorMessage = e.getMessage(); - } - - assertTrue(TextUtils.isEmpty(errorMessage)); - } catch (OlmException e) { - assertTrue("Exception Msg="+e.getMessage(), false); - } - - // SANITY CHECK TESTS FOR: decryptMessage() - String decryptedMsg = null; - try { - decryptedMsg = aliceSession.decryptMessage(null); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - assertTrue(null==decryptedMsg); - - // SANITY CHECK TESTS FOR: matchesInboundSession() - assertTrue(!aliceSession.matchesInboundSession(null)); - - // SANITY CHECK TESTS FOR: matchesInboundSessionFrom() - assertTrue(!aliceSession.matchesInboundSessionFrom(null,null)); - - // release objects - try { - bobAccount.removeOneTimeKeys(bobSession); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - aliceAccount.releaseAccount(); - bobAccount.releaseAccount(); - assertTrue(aliceAccount.isReleased()); - assertTrue(bobAccount.isReleased()); - - aliceSession.releaseSession(); - bobSession.releaseSession(); - assertTrue(aliceSession.isReleased()); - assertTrue(bobSession.isReleased()); - } - -} diff --git a/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmUtilityTest.java b/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmUtilityTest.java deleted file mode 100644 index b560bff..0000000 --- a/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmUtilityTest.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016 Vector Creations 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. - */ - -package org.matrix.olm; - -import android.support.test.runner.AndroidJUnit4; -import android.text.TextUtils; -import android.util.Log; - -import org.json.JSONObject; -import org.junit.BeforeClass; -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; - -import java.util.Map; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -@RunWith(AndroidJUnit4.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class OlmUtilityTest { - private static final String LOG_TAG = "OlmAccountTest"; - private static final int GENERATION_ONE_TIME_KEYS_NUMBER = 50; - - private static OlmManager mOlmManager; - - @BeforeClass - public static void setUpClass(){ - // load native lib - mOlmManager = new OlmManager(); - - String version = mOlmManager.getOlmLibVersion(); - assertNotNull(version); - Log.d(LOG_TAG, "## setUpClass(): lib version="+version); - } - - /** - * Test the signing API - */ - @Test - public void test01VerifyEd25519Signing() { - String fingerPrintKey = null; - String errorMsg = null; - String message = "{\"algorithms\":[\"m.megolm.v1.aes-sha2\",\"m.olm.v1.curve25519-aes-sha2\"],\"device_id\":\"YMBYCWTWCG\",\"keys\":{\"curve25519:YMBYCWTWCG\":\"KZFa5YUXV2EOdhK8dcGMMHWB67stdgAP4+xwiS69mCU\",\"ed25519:YMBYCWTWCG\":\"0cEgQJJqjgtXUGp4ZXQQmh36RAxwxr8HJw2E9v1gvA0\"},\"user_id\":\"@mxBob14774891254276b253f42-f267-43ec-bad9-767142bfea30:localhost:8480\"}"; - OlmAccount account = null; - - // create account - try { - account = new OlmAccount(); - } catch (OlmException e) { - assertTrue(e.getMessage(),false); - } - assertNotNull(account); - - // sign message - String messageSignature = null; - - try { - messageSignature = account.signMessage(message); - } catch (Exception e) { - assertTrue(e.getMessage(), false); - } - - assertNotNull(messageSignature); - - // get identities key (finger print key) - Map<String, String> identityKeys = null; - - try { - identityKeys = account.identityKeys(); - } catch (Exception e) { - assertTrue("identityKeys failed " + e.getMessage(), false); - } - - assertNotNull(identityKeys); - fingerPrintKey = TestHelper.getFingerprintKey(identityKeys); - assertTrue("fingerprint key missing",!TextUtils.isEmpty(fingerPrintKey)); - - // instantiate utility object - OlmUtility utility = null; - - try { - utility = new OlmUtility(); - } catch (Exception e) { - assertTrue("failed to create OlmUtility", false); - } - - // verify signature - errorMsg = null; - try { - utility.verifyEd25519Signature(messageSignature, fingerPrintKey, message); - } catch (Exception e) { - errorMsg = e.getMessage(); - } - assertTrue(TextUtils.isEmpty(errorMsg)); - - // check a bad signature is detected => errorMsg = BAD_MESSAGE_MAC - String badSignature = "Bad signature Bad signature Bad signature.."; - - errorMsg = null; - try { - utility.verifyEd25519Signature(badSignature, fingerPrintKey, message); - } catch (Exception e) { - errorMsg = e.getMessage(); - } - assertTrue(!TextUtils.isEmpty(errorMsg)); - - // check bad fingerprint size => errorMsg = INVALID_BASE64 - String badSizeFingerPrintKey = fingerPrintKey.substring(fingerPrintKey.length()/2); - - errorMsg = null; - try { - utility.verifyEd25519Signature(messageSignature, badSizeFingerPrintKey, message); - } catch (Exception e) { - errorMsg = e.getMessage(); - } - assertTrue(!TextUtils.isEmpty(errorMsg)); - - utility.releaseUtility(); - assertTrue(utility.isReleased()); - - account.releaseAccount(); - assertTrue(account.isReleased()); - } - - @Test - public void test02sha256() { - OlmUtility utility = null; - - try { - utility = new OlmUtility(); - } catch (Exception e) { - assertTrue("OlmUtility creation failed", false); - } - String msgToHash = "The quick brown fox jumps over the lazy dog"; - - String hashResult = utility.sha256(msgToHash); - assertFalse(TextUtils.isEmpty(hashResult)); - - utility.releaseUtility(); - assertTrue(utility.isReleased()); - } -} diff --git a/android/olm-sdk/src/androidTest/java/org/matrix/olm/TestHelper.java b/android/olm-sdk/src/androidTest/java/org/matrix/olm/TestHelper.java deleted file mode 100644 index 4451f7a..0000000 --- a/android/olm-sdk/src/androidTest/java/org/matrix/olm/TestHelper.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016 Vector Creations 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. - */ - -package org.matrix.olm; - -import java.util.ArrayList; -import java.util.Map; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -/** - * Helper class providing helper methods used in the Olm Android SDK unit tests. - */ -public class TestHelper { - - /** - * Return the identity key {@link OlmAccount#JSON_KEY_IDENTITY_KEY} from the JSON object. - * @param aIdentityKeysMap result of {@link OlmAccount#identityKeys()} - * @return identity key string if operation succeed, null otherwise - */ - static public String getIdentityKey(Map<String, String> aIdentityKeysMap){ - String idKey = null; - - try { - idKey = aIdentityKeysMap.get(OlmAccount.JSON_KEY_IDENTITY_KEY); - } catch (Exception e) { - assertTrue("Exception MSg=" + e.getMessage(), false); - } - return idKey; - } - - /** - * Return the fingerprint key {@link OlmAccount#JSON_KEY_FINGER_PRINT_KEY} from the JSON object. - * @param aIdentityKeysMap result of {@link OlmAccount#identityKeys()} - * @return fingerprint key string if operation succeed, null otherwise - */ - static public String getFingerprintKey(Map<String, String> aIdentityKeysMap) { - String fingerprintKey = null; - - try { - fingerprintKey = aIdentityKeysMap.get(OlmAccount.JSON_KEY_FINGER_PRINT_KEY); - } catch (Exception e) { - assertTrue("Exception MSg=" + e.getMessage(), false); - } - return fingerprintKey; - } - - /** - * Return the first one time key from the JSON object. - * @param aIdentityKeysMap result of {@link OlmAccount#oneTimeKeys()} - * @param aKeyPosition the position of the key to be retrieved - * @return one time key string if operation succeed, null otherwise - */ - static public String getOneTimeKey(Map<String, Map<String, String>> aIdentityKeysMap, int aKeyPosition) { - String firstOneTimeKey = null; - - try { - Map<String, String> generatedKeys = aIdentityKeysMap.get(OlmAccount.JSON_KEY_ONE_TIME_KEY); - assertNotNull(OlmAccount.JSON_KEY_ONE_TIME_KEY + " object is missing", generatedKeys); - - firstOneTimeKey = (new ArrayList<>(generatedKeys.values())).get(aKeyPosition - 1); - } catch (Exception e) { - assertTrue("Exception Msg=" + e.getMessage(), false); - } - return firstOneTimeKey; - } -} diff --git a/android/olm-sdk/src/main/AndroidManifest.xml b/android/olm-sdk/src/main/AndroidManifest.xml deleted file mode 100644 index 902f2e3..0000000 --- a/android/olm-sdk/src/main/AndroidManifest.xml +++ /dev/null @@ -1,8 +0,0 @@ -<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> diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/CommonSerializeUtils.java b/android/olm-sdk/src/main/java/org/matrix/olm/CommonSerializeUtils.java deleted file mode 100644 index 229963f..0000000 --- a/android/olm-sdk/src/main/java/org/matrix/olm/CommonSerializeUtils.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016 Vector Creations 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. - */ - -package org.matrix.olm; - -import android.util.Log; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -/** - * Helper class dedicated to serialization mechanism (template method pattern). - */ -abstract class CommonSerializeUtils { - private static final String LOG_TAG = "CommonSerializeUtils"; - - /** - * Kick off the serialization mechanism. - * @param aOutStream output stream for serializing - * @throws IOException exception - */ - protected void serialize(ObjectOutputStream aOutStream) throws IOException { - aOutStream.defaultWriteObject(); - - // generate serialization key - byte[] key = OlmUtility.getRandomKey(); - - // compute pickle string - StringBuffer errorMsg = new StringBuffer(); - byte[] pickledData = serialize(key, errorMsg); - - if(null == pickledData) { - throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_SERIALIZATION, String.valueOf(errorMsg)); - } else { - aOutStream.writeObject(new String(key, "UTF-8")); - aOutStream.writeObject(new String(pickledData, "UTF-8")); - } - } - - /** - * Kick off the deserialization mechanism. - * @param aInStream input stream - * @throws Exception the exception - */ - protected void deserialize(ObjectInputStream aInStream) throws Exception { - aInStream.defaultReadObject(); - - String keyAsString = (String)aInStream.readObject(); - String pickledDataAsString = (String)aInStream.readObject(); - - byte[] key; - byte[] pickledData; - - try { - key = keyAsString.getBytes("UTF-8"); - pickledData = pickledDataAsString.getBytes("UTF-8"); - - deserialize(pickledData, key); - } catch (Exception e) { - throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_DESERIALIZATION, e.getMessage()); - } - - Log.d(LOG_TAG,"## deserializeObject(): success"); - } - - protected abstract byte[] serialize(byte[] aKey, StringBuffer aErrorMsg); - protected abstract void deserialize(byte[] aSerializedData, byte[] aKey) throws Exception; -} diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java deleted file mode 100644 index 98a3c5b..0000000 --- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Copyright 2017 OpenMarket Ltd - * Copyright 2017 Vector Creations 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. - */ - -package org.matrix.olm; - -import android.text.TextUtils; -import android.util.Log; - -import org.json.JSONObject; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.Arrays; -import java.util.Map; - -/** - * Account class used to create Olm sessions in conjunction with {@link OlmSession} class.<br> - * OlmAccount provides APIs to retrieve the Olm keys. - *<br><br>Detailed implementation guide is available at <a href="http://matrix.org/docs/guides/e2e_implementation.html">Implementing End-to-End Encryption in Matrix clients</a>. - */ -public class OlmAccount extends CommonSerializeUtils implements Serializable { - private static final long serialVersionUID = 3497486121598434824L; - private static final String LOG_TAG = "OlmAccount"; - - // JSON keys used in the JSON objects returned by JNI - /** As well as the identity key, each device creates a number of Curve25519 key pairs which are - also used to establish Olm sessions, but can only be used once. Once again, the private part - remains on the device. but the public part is published to the Matrix network **/ - public static final String JSON_KEY_ONE_TIME_KEY = "curve25519"; - - /** Curve25519 identity key is a public-key cryptographic system which can be used to establish a shared - secret.<br>In Matrix, each device has a long-lived Curve25519 identity key which is used to establish - Olm sessions with that device. The private key should never leave the device, but the - public part is signed with the Ed25519 fingerprint key ({@link #JSON_KEY_FINGER_PRINT_KEY}) and published to the network. **/ - public static final String JSON_KEY_IDENTITY_KEY = "curve25519"; - - /** Ed25519 finger print is a public-key cryptographic system for signing messages.<br>In Matrix, each device has - an Ed25519 key pair which serves to identify that device. The private the key should - never leave the device, but the public part is published to the Matrix network. **/ - public static final String JSON_KEY_FINGER_PRINT_KEY = "ed25519"; - - /** Account Id returned by JNI. - * This value identifies uniquely the native account instance. - */ - private transient long mNativeId; - - public OlmAccount() throws OlmException { - try { - mNativeId = createNewAccountJni(); - } catch (Exception e) { - throw new OlmException(OlmException.EXCEPTION_CODE_INIT_ACCOUNT_CREATION, e.getMessage()); - } - } - - /** - * Create a new account and return it to JAVA side.<br> - * Since a C prt is returned as a jlong, special care will be taken - * to make the cast (OlmAccount* to jlong) platform independent. - * @return the initialized OlmAccount* instance or throw an exception if fails - **/ - private native long createNewAccountJni(); - - /** - * Getter on the account ID. - * @return native account ID - */ - long getOlmAccountId(){ - return mNativeId; - } - - /** - * Release native account and invalid its JAVA reference counter part.<br> - * Public API for {@link #releaseAccountJni()}. - */ - public void releaseAccount() { - if (0 != mNativeId) { - releaseAccountJni(); - } - mNativeId = 0; - } - - /** - * Destroy the corresponding OLM account native object.<br> - * This method must ALWAYS be called when this JAVA instance - * is destroyed (ie. garbage collected) to prevent memory leak in native side. - * See {@link #createNewAccountJni()}. - */ - private native void releaseAccountJni(); - - /** - * Return true the object resources have been released.<br> - * @return true the object resources have been released - */ - public boolean isReleased() { - return (0 == mNativeId); - } - - /** - * Return the identity keys (identity and fingerprint keys) in a dictionary.<br> - * Public API for {@link #identityKeysJni()}.<br> - * Ex:<tt> - * { - * "curve25519":"Vam++zZPMqDQM6ANKpO/uAl5ViJSHxV9hd+b0/fwRAg", - * "ed25519":"+v8SOlOASFTMrX3MCKBM4iVnYoZ+JIjpNt1fi8Z9O2I" - * }</tt> - * @return identity keys dictionary if operation succeeds, null otherwise - * @exception OlmException the failure reason - */ - public Map<String, String> identityKeys() throws OlmException { - JSONObject identityKeysJsonObj = null; - - byte[] identityKeysBuffer; - - try { - identityKeysBuffer = identityKeysJni(); - } catch (Exception e) { - Log.e(LOG_TAG, "## identityKeys(): Failure - " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_IDENTITY_KEYS, e.getMessage()); - } - - if (null != identityKeysBuffer) { - try { - identityKeysJsonObj = new JSONObject(new String(identityKeysBuffer, "UTF-8")); - } catch (Exception e) { - Log.e(LOG_TAG, "## identityKeys(): Exception - Msg=" + e.getMessage()); - } - } else { - Log.e(LOG_TAG, "## identityKeys(): Failure - identityKeysJni()=null"); - } - - return OlmUtility.toStringMap(identityKeysJsonObj); - } - - /** - * Get the public identity keys (Ed25519 fingerprint key and Curve25519 identity key).<br> - * Keys are Base64 encoded. - * These keys must be published on the server. - * @return the identity keys or throw an exception if it fails - */ - private native byte[] identityKeysJni(); - - /** - * Return the largest number of "one time keys" this account can store. - * @return the max number of "one time keys", -1 otherwise - */ - public long maxOneTimeKeys() { - return maxOneTimeKeysJni(); - } - - /** - * Return the largest number of "one time keys" this account can store. - * @return the max number of "one time keys", -1 otherwise - */ - private native long maxOneTimeKeysJni(); - - /** - * Generate a number of new one time keys.<br> If total number of keys stored - * by this account exceeds {@link #maxOneTimeKeys()}, the old keys are discarded.<br> - * The corresponding keys are retrieved by {@link #oneTimeKeys()}. - * @param aNumberOfKeys number of keys to generate - * @exception OlmException the failure reason - */ - public void generateOneTimeKeys(int aNumberOfKeys) throws OlmException { - try { - generateOneTimeKeysJni(aNumberOfKeys); - } catch (Exception e) { - throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_GENERATE_ONE_TIME_KEYS, e.getMessage()); - } - } - - /** - * Generate a number of new one time keys.<br> If total number of keys stored - * by this account exceeds {@link #maxOneTimeKeys()}, the old keys are discarded. - * An exception is thrown if the operation fails.<br> - * @param aNumberOfKeys number of keys to generate - */ - private native void generateOneTimeKeysJni(int aNumberOfKeys); - - /** - * Return the "one time keys" in a dictionary.<br> - * The number of "one time keys", is specified by {@link #generateOneTimeKeys(int)}<br> - * Ex:<tt> - * { "curve25519": - * { - * "AAAABQ":"qefVZd8qvjOpsFzoKSAdfUnJVkIreyxWFlipCHjSQQg", - * "AAAABA":"/X8szMU+p+lsTnr56wKjaLgjTMQQkCk8EIWEAilZtQ8", - * "AAAAAw":"qxNxxFHzevFntaaPdT0fhhO7tc7pco4+xB/5VRG81hA", - * } - * }</tt><br> - * Public API for {@link #oneTimeKeysJni()}.<br> - * Note: these keys are to be published on the server. - * @return one time keys in string dictionary. - * @exception OlmException the failure reason - */ - public Map<String, Map<String, String>> oneTimeKeys() throws OlmException { - JSONObject oneTimeKeysJsonObj = null; - byte[] oneTimeKeysBuffer; - - try { - oneTimeKeysBuffer = oneTimeKeysJni(); - } catch (Exception e) { - throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_ONE_TIME_KEYS, e.getMessage()); - } - - if( null != oneTimeKeysBuffer) { - try { - oneTimeKeysJsonObj = new JSONObject(new String(oneTimeKeysBuffer, "UTF-8")); - } catch (Exception e) { - Log.e(LOG_TAG, "## oneTimeKeys(): Exception - Msg=" + e.getMessage()); - } - } else { - Log.e(LOG_TAG, "## oneTimeKeys(): Failure - identityKeysJni()=null"); - } - - return OlmUtility.toStringMapMap(oneTimeKeysJsonObj); - } - - /** - * 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 - * <tt>curve25519</tt>, which is itself an object mapping key id to - * base64-encoded Curve25519 key.<br> - * @return byte array containing the one time keys or throw an exception if it fails - */ - private native byte[] oneTimeKeysJni(); - - /** - * Remove the "one time keys" that the session used from the account. - * @param aSession session instance - * @throws OlmException the failure reason - */ - public void removeOneTimeKeys(OlmSession aSession) throws OlmException { - if (null != aSession) { - try { - removeOneTimeKeysJni(aSession.getOlmSessionId()); - } catch (Exception e) { - throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_REMOVE_ONE_TIME_KEYS, e.getMessage()); - } - } - } - - /** - * Remove the "one time keys" that the session used from the account. - * An exception is thrown if the operation fails. - * @param aNativeOlmSessionId native session instance identifier - */ - private native void removeOneTimeKeysJni(long aNativeOlmSessionId); - - /** - * Marks the current set of "one time keys" as being published. - * @exception OlmException the failure reason - */ - public void markOneTimeKeysAsPublished() throws OlmException { - try { - markOneTimeKeysAsPublishedJni(); - } catch (Exception e) { - throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_MARK_ONE_KEYS_AS_PUBLISHED, e.getMessage()); - } - } - - /** - * Marks the current set of "one time keys" as being published. - * An exception is thrown if the operation fails. - */ - private native void markOneTimeKeysAsPublishedJni(); - - /** - * Sign a message with the ed25519 fingerprint key for this account.<br> - * The signed message is returned by the method. - * @param aMessage message to sign - * @return the signed message - * @exception OlmException the failure reason - */ - public String signMessage(String aMessage) throws OlmException { - String result = null; - - if (null != aMessage) { - byte[] utf8String = null; - try { - utf8String = aMessage.getBytes("UTF-8"); - if (null != utf8String) { - byte[] signedMessage = signMessageJni(utf8String); - - if (null != signedMessage) { - result = new String(signedMessage, "UTF-8"); - } - } - } catch (Exception e) { - throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_SIGN_MESSAGE, e.getMessage()); - } finally { - if (null != utf8String) { - Arrays.fill(utf8String, (byte) 0); - } - } - } - - return result; - } - - /** - * Sign a message with the ed25519 fingerprint key for this account.<br> - * The signed message is returned by the method. - * @param aMessage message to sign - * @return the signed message - */ - private native byte[] signMessageJni(byte[] aMessage); - - //============================================================================================================== - // Serialization management - //============================================================================================================== - - /** - * Kick off the serialization mechanism. - * @param aOutStream output stream for serializing - * @throws IOException exception - */ - private void writeObject(ObjectOutputStream aOutStream) throws IOException { - serialize(aOutStream); - } - - /** - * Kick off the deserialization mechanism. - * @param aInStream input stream - * @throws Exception exception - */ - private void readObject(ObjectInputStream aInStream) throws Exception { - deserialize(aInStream); - } - - /** - * Return an 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 account as bytes buffer - */ - @Override - protected byte[] serialize(byte[] aKey, StringBuffer aErrorMsg) { - byte[] pickleRetValue = null; - - // sanity check - if(null == aErrorMsg) { - Log.e(LOG_TAG,"## serialize(): invalid parameter - aErrorMsg=null"); - } else if (null == aKey) { - aErrorMsg.append("Invalid input parameters in serializeDataWithKey()"); - } else { - aErrorMsg.setLength(0); - try { - pickleRetValue = serializeJni(aKey); - } catch (Exception e) { - Log.e(LOG_TAG, "## serialize() failed " + e.getMessage()); - aErrorMsg.append(e.getMessage()); - } - } - - return pickleRetValue; - } - - /** - * Serialize and encrypt account instance.<br> - * @param aKeyBuffer key used to encrypt the serialized account data - * @return the serialised account as bytes buffer. - **/ - private native byte[] serializeJni(byte[] aKeyBuffer); - - /** - * 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 - */ - @Override - protected void deserialize(byte[] aSerializedData, byte[] aKey) throws Exception { - String errorMsg = null; - - try { - if ((null == aSerializedData) || (null == aKey)) { - Log.e(LOG_TAG, "## deserialize(): invalid input parameters"); - errorMsg = "invalid input parameters"; - } else { - mNativeId = deserializeJni(aSerializedData, aKey); - } - } catch (Exception e) { - Log.e(LOG_TAG, "## deserialize() failed " + e.getMessage()); - errorMsg = e.getMessage(); - } - - if (!TextUtils.isEmpty(errorMsg)) { - releaseAccount(); - throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_DESERIALIZATION, errorMsg); - } - } - - /** - * Allocate a new account and initialize it with the serialisation data.<br> - * @param aSerializedDataBuffer the account serialisation buffer - * @param aKeyBuffer the key used to encrypt the serialized account data - * @return the deserialized account - **/ - private native long deserializeJni(byte[] aSerializedDataBuffer, byte[] aKeyBuffer); -} diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmException.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmException.java deleted file mode 100644 index 5b4a85a..0000000 --- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmException.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2017 OpenMarket Ltd - * Copyright 2017-2019 Vector Creations 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. - */ - -package org.matrix.olm; - -import java.io.IOException; - -/** - * Exception class to identify specific Olm SDK exceptions. - */ -public class OlmException extends IOException { - // exception codes - - public static final int EXCEPTION_CODE_INIT_ACCOUNT_CREATION = 10; - - public static final int EXCEPTION_CODE_ACCOUNT_SERIALIZATION = 100; - public static final int EXCEPTION_CODE_ACCOUNT_DESERIALIZATION = 101; - public static final int EXCEPTION_CODE_ACCOUNT_IDENTITY_KEYS = 102; - public static final int EXCEPTION_CODE_ACCOUNT_GENERATE_ONE_TIME_KEYS = 103; - public static final int EXCEPTION_CODE_ACCOUNT_ONE_TIME_KEYS = 104; - 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_SIGN_MESSAGE = 107; - - 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_INBOUND_GROUP_SESSION_IDENTIFIER = 202; - public static final int EXCEPTION_CODE_INBOUND_GROUP_SESSION_DECRYPT_SESSION = 203; - public static final int EXCEPTION_CODE_INBOUND_GROUP_SESSION_FIRST_KNOWN_INDEX = 204; - public static final int EXCEPTION_CODE_INBOUND_GROUP_SESSION_IS_VERIFIED = 205; - public static final int EXCEPTION_CODE_INBOUND_GROUP_SESSION_EXPORT = 206; - - public static final int EXCEPTION_CODE_CREATE_OUTBOUND_GROUP_SESSION = 300; - public static final int EXCEPTION_CODE_INIT_OUTBOUND_GROUP_SESSION = 301; - public static final int EXCEPTION_CODE_OUTBOUND_GROUP_SESSION_IDENTIFIER = 302; - public static final int EXCEPTION_CODE_OUTBOUND_GROUP_SESSION_KEY = 303; - public static final int EXCEPTION_CODE_OUTBOUND_GROUP_ENCRYPT_MESSAGE = 304; - - public static final int EXCEPTION_CODE_INIT_SESSION_CREATION = 400; - public static final int EXCEPTION_CODE_SESSION_INIT_OUTBOUND_SESSION = 401; - public static final int EXCEPTION_CODE_SESSION_INIT_INBOUND_SESSION = 402; - public static final int EXCEPTION_CODE_SESSION_INIT_INBOUND_SESSION_FROM = 403; - 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_SESSION_IDENTIFIER = 406; - - 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_PK_ENCRYPTION_CREATION = 600; - public static final int EXCEPTION_CODE_PK_ENCRYPTION_SET_RECIPIENT_KEY = 601; - public static final int EXCEPTION_CODE_PK_ENCRYPTION_ENCRYPT = 602; - - public static final int EXCEPTION_CODE_PK_DECRYPTION_CREATION = 700; - public static final int EXCEPTION_CODE_PK_DECRYPTION_GENERATE_KEY = 701; - public static final int EXCEPTION_CODE_PK_DECRYPTION_DECRYPT = 702; - public static final int EXCEPTION_CODE_PK_DECRYPTION_SET_PRIVATE_KEY = 703; - public static final int EXCEPTION_CODE_PK_DECRYPTION_PRIVATE_KEY = 704; - - public static final int EXCEPTION_CODE_PK_SIGNING_CREATION = 800; - public static final int EXCEPTION_CODE_PK_SIGNING_GENERATE_SEED = 801; - public static final int EXCEPTION_CODE_PK_SIGNING_INIT_WITH_SEED = 802; - public static final int EXCEPTION_CODE_PK_SIGNING_SIGN = 803; - - public static final int EXCEPTION_CODE_SAS_CREATION = 900; - public static final int EXCEPTION_CODE_SAS_ERROR = 901; - public static final int EXCEPTION_CODE_SAS_MISSING_THEIR_PKEY = 902; - public static final int EXCEPTION_CODE_SAS_GENERATE_SHORT_CODE = 903; - - // exception human readable messages - public static final String EXCEPTION_MSG_INVALID_PARAMS_DESERIALIZATION = "invalid de-serialized parameters"; - - /** exception code to be taken from: {@link #EXCEPTION_CODE_CREATE_OUTBOUND_GROUP_SESSION}, {@link #EXCEPTION_CODE_CREATE_INBOUND_GROUP_SESSION}, - * {@link #EXCEPTION_CODE_INIT_OUTBOUND_GROUP_SESSION}, {@link #EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION}..**/ - private final int mCode; - - /** Human readable message description **/ - private final String mMessage; - - public OlmException(int aExceptionCode, String aExceptionMessage) { - super(); - mCode = aExceptionCode; - mMessage = aExceptionMessage; - } - - public int getExceptionCode() { - return mCode; - } - - @Override - public String getMessage() { - return mMessage; - } -} diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java deleted file mode 100644 index 2fc81ef..0000000 --- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java +++ /dev/null @@ -1,372 +0,0 @@ -/* - * Copyright 2017 OpenMarket Ltd - * Copyright 2017 Vector Creations 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. - */ - -package org.matrix.olm; - -import android.text.TextUtils; -import android.util.Log; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; - -import java.util.Arrays; - -/** - * Class used to create an inbound <a href="http://matrix.org/docs/guides/e2e_implementation.html#handling-an-m-room-key-event">Megolm session</a>.<br> - * Counter part of the outbound group session {@link OlmOutboundGroupSession}, this class decrypts the messages sent by the outbound side. - * - * <br><br>Detailed implementation guide is available at <a href="http://matrix.org/docs/guides/e2e_implementation.html">Implementing End-to-End Encryption in Matrix clients</a>. - */ -public class OlmInboundGroupSession extends CommonSerializeUtils implements Serializable { - private static final long serialVersionUID = -772028491251653253L; - private static final String LOG_TAG = "OlmInboundGroupSession"; - - /** Session Id returned by JNI.<br> - * This value uniquely identifies the native inbound group session instance. - */ - private transient long mNativeId; - - /** - * Result in {@link #decryptMessage(String)} - */ - public static class DecryptMessageResult { - /** decrypt message **/ - public String mDecryptedMessage; - - /** decrypt index **/ - public long mIndex; - } - - /** - * Constructor.<br> - * Create and save a new native session instance ID and start a new inbound group session. - * The session key parameter is retrieved from an outbound group session. - * @param aSessionKey session key - * @throws OlmException constructor failure - */ - public OlmInboundGroupSession(String aSessionKey) throws OlmException { - this(aSessionKey, false); - } - - /** - * Constructor.<br> - * Create and save a new native session instance ID and start a new inbound group session. - * The session key parameter is retrieved from an outbound group session. - * @param aSessionKey session key - * @param isImported true when the session key has been retrieved from a backup - * @throws OlmException constructor failure - */ - private OlmInboundGroupSession(String aSessionKey, boolean isImported) throws OlmException { - if (TextUtils.isEmpty(aSessionKey)) { - Log.e(LOG_TAG, "## initInboundGroupSession(): invalid session key"); - throw new OlmException(OlmException.EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION, "invalid session key"); - } else { - byte[] sessionBuffer = null; - try { - sessionBuffer = aSessionKey.getBytes("UTF-8"); - mNativeId = createNewSessionJni(aSessionKey.getBytes("UTF-8"), isImported); - } catch (Exception e) { - throw new OlmException(OlmException.EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION, e.getMessage()); - } finally { - if (null != sessionBuffer) { - Arrays.fill(sessionBuffer, (byte) 0); - } - } - } - } - - /** - * Initialize a new inbound group session and return it to JAVA side.<br> - * Since a C prt is returned as a jlong, special care will be taken - * to make the cast (OlmInboundGroupSession* to jlong) platform independent. - * @param aSessionKeyBuffer session key from an outbound session - * @param isImported true when the session key has been retrieved from a backup - * @return the initialized OlmInboundGroupSession* instance or throw an exception it fails. - **/ - private native long createNewSessionJni(byte[] aSessionKeyBuffer, boolean isImported); - - /** - * Create an OlmInboundGroupSession from its exported session data. - * @param exported the exported data - * @return the created OlmException - * @throws OlmException the failure reason - */ - public static OlmInboundGroupSession importSession(String exported) throws OlmException { - return new OlmInboundGroupSession(exported, true); - } - - /** - * Release native session and invalid its JAVA reference counter part.<br> - * Public API for {@link #releaseSessionJni()}. - */ - public void releaseSession(){ - if (0 != mNativeId) { - releaseSessionJni(); - } - mNativeId = 0; - } - - /** - * Destroy the corresponding OLM inbound group session native object.<br> - * This method must ALWAYS be called when this JAVA instance - * is destroyed (ie. garbage collected) to prevent memory leak in native side. - * See {@link #createNewSessionJni(byte[], boolean)}. - */ - private native void releaseSessionJni(); - - /** - * Return true the object resources have been released.<br> - * @return true the object resources have been released - */ - public boolean isReleased() { - return (0 == mNativeId); - } - - /** - * Retrieve the base64-encoded identifier for this inbound group session. - * @return the session ID - * @throws OlmException the failure reason - */ - public String sessionIdentifier() throws OlmException { - try { - return new String(sessionIdentifierJni(), "UTF-8"); - } catch (Exception e) { - Log.e(LOG_TAG, "## sessionIdentifier() failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_INBOUND_GROUP_SESSION_IDENTIFIER, e.getMessage()); - } - } - - /** - * Get a base64-encoded identifier for this inbound group session. - * An exception is thrown if the operation fails. - * @return the base64-encoded identifier - */ - private native byte[] sessionIdentifierJni(); - - /** - * Provides the first known index. - * @return the first known index. - * @throws OlmException the failure reason - */ - public long getFirstKnownIndex() throws OlmException { - long index = 0; - - try { - index = firstKnownIndexJni(); - } catch (Exception e) { - Log.e(LOG_TAG, "## getFirstKnownIndex() failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_INBOUND_GROUP_SESSION_FIRST_KNOWN_INDEX, e.getMessage()); - } - - return index; - } - - /** - * Provides the first known index. - * An exception is thrown if the operation fails. - * @return the first known index. - */ - private native long firstKnownIndexJni(); - - /** - * Tells if the session is verified. - * @return true if the session is verified - * @throws OlmException the failure reason - */ - public boolean isVerified() throws OlmException { - boolean isVerified; - - try { - isVerified = isVerifiedJni(); - } catch (Exception e) { - Log.e(LOG_TAG, "## isVerified() failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_INBOUND_GROUP_SESSION_IS_VERIFIED, e.getMessage()); - } - - return isVerified; - } - - /** - * Tells if the session is verified. - * @return true if the session is verified - */ - private native boolean isVerifiedJni(); - - /** - * Export the session from a message index as String. - * @param messageIndex the message index - * @return the session as String - * @throws OlmException the failure reason - */ - public String export(long messageIndex) throws OlmException { - String result = null; - - try { - byte[] bytesBuffer = exportJni(messageIndex); - - if (null != bytesBuffer) { - result = new String(bytesBuffer, "UTF-8"); - Arrays.fill(bytesBuffer, (byte) 0); - } - } catch (Exception e) { - Log.e(LOG_TAG, "## export() failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_INBOUND_GROUP_SESSION_EXPORT, e.getMessage()); - } - - return result; - } - - /** - * Exports the session as byte array from a message index - * An exception is thrown if the operation fails. - * @param messageIndex key used to encrypt the serialized session data - * @return the session saved as bytes array - */ - private native byte[] exportJni(long messageIndex); - - /** - * Decrypt the message passed in parameter.<br> - * In case of error, null is returned and an error message description is provided in aErrorMsg. - * @param aEncryptedMsg the message to be decrypted - * @return the decrypted message information - * @exception OlmException the failure reason - */ - public DecryptMessageResult decryptMessage(String aEncryptedMsg) throws OlmException { - DecryptMessageResult result = new DecryptMessageResult(); - - try { - byte[] decryptedMessageBuffer = decryptMessageJni(aEncryptedMsg.getBytes("UTF-8"), result); - - if (null != decryptedMessageBuffer) { - result.mDecryptedMessage = new String(decryptedMessageBuffer, "UTF-8"); - Arrays.fill(decryptedMessageBuffer, (byte) 0); - } - } catch (Exception e) { - Log.e(LOG_TAG, "## decryptMessage() failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_INBOUND_GROUP_SESSION_DECRYPT_SESSION, e.getMessage()); - } - - return result; - } - - /** - * Decrypt a message. - * An exception is thrown if the operation fails. - * @param aEncryptedMsg the encrypted message - * @param aDecryptMessageResult the decryptMessage information - * @return the decrypted message - */ - private native byte[] decryptMessageJni(byte[] aEncryptedMsg, DecryptMessageResult aDecryptMessageResult); - - //============================================================================================================== - // Serialization management - //============================================================================================================== - - /** - * Kick off the serialization mechanism. - * @param aOutStream output stream for serializing - * @throws IOException exception - */ - private void writeObject(ObjectOutputStream aOutStream) throws IOException { - serialize(aOutStream); - } - - /** - * Kick off the deserialization mechanism. - * @param aInStream input stream - * @throws Exception exception - */ - private void readObject(ObjectInputStream aInStream) throws Exception { - deserialize(aInStream); - } - - /** - * Return the current 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 pickled bytes buffer if operation succeed, null otherwise - */ - @Override - protected byte[] serialize(byte[] aKey, StringBuffer aErrorMsg) { - byte[] pickleRetValue = null; - - // sanity check - if(null == aErrorMsg) { - Log.e(LOG_TAG,"## serialize(): invalid parameter - aErrorMsg=null"); - } else if (null == aKey) { - aErrorMsg.append("Invalid input parameters in serialize()"); - } else { - aErrorMsg.setLength(0); - try { - pickleRetValue = serializeJni(aKey); - } catch (Exception e) { - Log.e(LOG_TAG, "## serialize() failed " + e.getMessage()); - aErrorMsg.append(e.getMessage()); - } - } - - return pickleRetValue; - } - /** - * JNI counter part of {@link #serialize(byte[], StringBuffer)}. - * @param aKey encryption key - * @return the serialized session - */ - private native byte[] serializeJni(byte[] aKey); - - /** - * Loads an account from a pickled base64 string.<br> - * See {@link #serialize(byte[], StringBuffer)} - * @param aSerializedData pickled account in a bytes buffer - * @param aKey key used to encrypted - */ - @Override - protected void deserialize(byte[] aSerializedData, byte[] aKey) throws Exception { - String errorMsg = null; - - try { - if ((null == aSerializedData) || (null == aKey)) { - Log.e(LOG_TAG, "## deserialize(): invalid input parameters"); - errorMsg = "invalid input parameters"; - } else { - mNativeId = deserializeJni(aSerializedData, aKey); - } - } catch (Exception e) { - Log.e(LOG_TAG, "## deserialize() failed " + e.getMessage()); - errorMsg = e.getMessage(); - } - - if (!TextUtils.isEmpty(errorMsg)) { - releaseSession(); - throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_DESERIALIZATION, errorMsg); - } - } - - /** - * Allocate a new session and initialize it with the serialisation data.<br> - * An exception is thrown if the operation fails. - * @param aSerializedData the session serialisation buffer - * @param aKey the key used to encrypt the serialized account data - * @return the deserialized session - **/ - private native long deserializeJni(byte[] aSerializedData, byte[] aKey); -} diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmManager.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmManager.java deleted file mode 100644 index cd33a5a..0000000 --- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmManager.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016 Vector Creations 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. - */ - -package org.matrix.olm; - -import android.content.Context; -import android.util.Log; - -/** - * Olm SDK entry point class.<br> An OlmManager instance must be created at first to enable native library load. - * <br><br>Detailed implementation guide is available at <a href="http://matrix.org/docs/guides/e2e_implementation.html">Implementing End-to-End Encryption in Matrix clients</a>. - */ -public class OlmManager { - private static final String LOG_TAG = "OlmManager"; - - /** - * Constructor. - */ - public OlmManager() { - } - - static { - try { - java.lang.System.loadLibrary("olm"); - } catch(UnsatisfiedLinkError e) { - Log.e(LOG_TAG,"Exception loadLibrary() - Msg="+e.getMessage()); - } - } - - /** - * Provide the android library version - * @return the library version - */ - public String getVersion() { - return BuildConfig.VERSION_NAME; - } - - /** - * Provide a detailed version. - * It contains the android and the native libraries versions. - * @param context the context - * @return the detailed version - */ - public String getDetailedVersion(Context context) { - String gitVersion = context.getResources().getString(R.string.git_olm_revision); - String date = context.getResources().getString(R.string.git_olm_revision_date); - return getVersion() + " - olm version (" + getOlmLibVersion() + ") - " + gitVersion + "-" + date; - } - - /** - * Provide the native OLM lib version. - * @return the lib version as a string - */ - public String getOlmLibVersion(){ - return getOlmLibVersionJni(); - } - public native String getOlmLibVersionJni(); -} - diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmMessage.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmMessage.java deleted file mode 100644 index 08db993..0000000 --- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmMessage.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016 Vector Creations 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. - */ - -package org.matrix.olm; - -/** - * Message class used in Olm sessions to contain the encrypted data.<br> - * See {@link OlmSession#decryptMessage(OlmMessage)} and {@link OlmSession#encryptMessage(String)}. - * <br>Detailed implementation guide is available at <a href="http://matrix.org/docs/guides/e2e_implementation.html">Implementing End-to-End Encryption in Matrix clients</a>. - */ -public class OlmMessage { - /** PRE KEY message type (used to establish new Olm session) **/ - public final static int MESSAGE_TYPE_PRE_KEY = 0; - /** normal message type **/ - public final static int MESSAGE_TYPE_MESSAGE = 1; - - /** the encrypted message **/ - public String mCipherText; - - /** defined by {@link #MESSAGE_TYPE_MESSAGE} or {@link #MESSAGE_TYPE_PRE_KEY}**/ - public long mType; -} diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmOutboundGroupSession.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmOutboundGroupSession.java deleted file mode 100644 index 55732fe..0000000 --- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmOutboundGroupSession.java +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright 2017 OpenMarket Ltd - * Copyright 2017 Vector Creations 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. - */ - -package org.matrix.olm; - - -import android.text.TextUtils; -import android.util.Log; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; - -import java.util.Arrays; - -/** - * Class used to create an outbound a <a href="http://matrix.org/docs/guides/e2e_implementation.html#starting-a-megolm-session">Megolm session</a>.<br> - * To send a first message in an encrypted room, the client should start a new outbound Megolm session. - * The session ID and the session key must be shared with each device in the room within. - * - * <br><br>Detailed implementation guide is available at <a href="http://matrix.org/docs/guides/e2e_implementation.html">Implementing End-to-End Encryption in Matrix clients</a>. - */ -public class OlmOutboundGroupSession extends CommonSerializeUtils implements Serializable { - private static final long serialVersionUID = -3133097431283604416L; - private static final String LOG_TAG = "OlmOutboundGroupSession"; - - /** Session Id returned by JNI.<br> - * This value uniquely identifies the native outbound group session instance. - */ - private transient long mNativeId; - - /** - * Constructor.<br> - * Create and save a new session native instance ID and - * initialise a new outbound group session.<br> - * @throws OlmException constructor failure - */ - public OlmOutboundGroupSession() throws OlmException { - try { - mNativeId = createNewSessionJni(); - } catch (Exception e) { - throw new OlmException(OlmException.EXCEPTION_CODE_CREATE_OUTBOUND_GROUP_SESSION, e.getMessage()); - } - } - - /** - * Create the corresponding OLM outbound group session in native side.<br> - * An exception is thrown if the operation fails. - * Do not forget to call {@link #releaseSession()} when JAVA side is done. - * @return native session instance identifier (see {@link #mNativeId}) - */ - private native long createNewSessionJni(); - - /** - * Release native session and invalid its JAVA reference counter part.<br> - * Public API for {@link #releaseSessionJni()}. - */ - public void releaseSession() { - if (0 != mNativeId) { - releaseSessionJni(); - } - mNativeId = 0; - } - - /** - * Destroy the corresponding OLM outbound group session native object.<br> - * This method must ALWAYS be called when this JAVA instance - * is destroyed (ie. garbage collected) to prevent memory leak in native side. - * See {@link #createNewSessionJni()}. - */ - private native void releaseSessionJni(); - - /** - * Return true the object resources have been released.<br> - * @return true the object resources have been released - */ - public boolean isReleased() { - return (0 == mNativeId); - } - - /** - * Get a base64-encoded identifier for this session. - * @return session identifier - * @throws OlmException the failure reason - */ - public String sessionIdentifier() throws OlmException { - try { - return new String(sessionIdentifierJni(), "UTF-8"); - } catch (Exception e) { - Log.e(LOG_TAG, "## sessionIdentifier() failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_OUTBOUND_GROUP_SESSION_IDENTIFIER, e.getMessage()); - } - } - - /** - * Return the session identifier. - * An exception is thrown if the operation fails. - * @return the session identifier - */ - private native byte[] sessionIdentifierJni(); - - /** - * Get the current message index for this session.<br> - * Each message is sent with an increasing index, this - * method returns the index for the next message. - * @return current session index - */ - public int messageIndex() { - return messageIndexJni(); - } - - /** - * Get the current message index for this session.<br> - * Each message is sent with an increasing index, this - * method returns the index for the next message. - * An exception is thrown if the operation fails. - * @return current session index - */ - private native int messageIndexJni(); - - /** - * Get the base64-encoded current ratchet key for this session.<br> - * Each message is sent with a different ratchet key. This method returns the - * ratchet key that will be used for the next message. - * @return outbound session key - * @exception OlmException the failure reason - */ - public String sessionKey() throws OlmException { - try { - byte[] sessionKeyBuffer = sessionKeyJni(); - String ret = new String(sessionKeyBuffer, "UTF-8"); - Arrays.fill(sessionKeyBuffer, (byte) 0); - return ret; - } catch (Exception e) { - Log.e(LOG_TAG, "## sessionKey() failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_OUTBOUND_GROUP_SESSION_KEY, e.getMessage()); - } - } - - /** - * Return the session key. - * An exception is thrown if the operation fails. - * @return the session key - */ - private native byte[] sessionKeyJni(); - - /** - * Encrypt some plain-text message.<br> - * The message given as parameter is encrypted and returned as the return value. - * @param aClearMsg message to be encrypted - * @return the encrypted message - * @exception OlmException the encryption failure reason - */ - public String encryptMessage(String aClearMsg) throws OlmException { - String retValue = null; - - if (!TextUtils.isEmpty(aClearMsg)) { - try { - byte[] clearMsgBuffer = aClearMsg.getBytes("UTF-8"); - byte[] encryptedBuffer = encryptMessageJni(clearMsgBuffer); - Arrays.fill(clearMsgBuffer, (byte) 0); - - if (null != encryptedBuffer) { - retValue = new String(encryptedBuffer , "UTF-8"); - } - } catch (Exception e) { - Log.e(LOG_TAG, "## encryptMessage() failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_OUTBOUND_GROUP_ENCRYPT_MESSAGE, e.getMessage()); - } - } - - return retValue; - } - - /** - * Encrypt a bytes buffer messages. - * An exception is thrown if the operation fails. - * @param aClearMsgBuffer the message to encode - * @return the encoded message - */ - private native byte[] encryptMessageJni(byte[] aClearMsgBuffer); - - //============================================================================================================== - // Serialization management - //============================================================================================================== - - /** - * Kick off the serialization mechanism. - * @param aOutStream output stream for serializing - * @throws IOException exception - */ - private void writeObject(ObjectOutputStream aOutStream) throws IOException { - serialize(aOutStream); - } - - /** - * Kick off the deserialization mechanism. - * @param aInStream input stream - * @throws Exception exception - */ - private void readObject(ObjectInputStream aInStream) throws Exception { - deserialize(aInStream); - } - - /** - * Return the current outbound group session as a base64 byte buffers.<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 pickled base64 bytes buffer if operation succeed, null otherwise - */ - @Override - protected byte[] serialize(byte[] aKey, StringBuffer aErrorMsg) { - byte[] pickleRetValue = null; - - // sanity check - if(null == aErrorMsg) { - Log.e(LOG_TAG,"## serialize(): invalid parameter - aErrorMsg=null"); - } else if (null == aKey) { - aErrorMsg.append("Invalid input parameters in serialize()"); - } else { - try { - pickleRetValue = serializeJni(aKey); - } catch (Exception e) { - Log.e(LOG_TAG,"## serialize(): failed " + e.getMessage()); - aErrorMsg.append(e.getMessage()); - } - } - - return pickleRetValue; - } - - /** - * JNI counter part of {@link #serialize(byte[], StringBuffer)}. - * An exception is thrown if the operation fails. - * @param aKey encryption key - * @return the serialized session - */ - private native byte[] serializeJni(byte[] aKey); - - /** - * Loads an account from a pickled base64 string.<br> - * See {@link #serialize(byte[], StringBuffer)} - * @param aSerializedData pickled account in a base64 bytes buffer - * @param aKey key used to encrypted - * @exception Exception the exception - */ - @Override - protected void deserialize(byte[] aSerializedData, byte[] aKey) throws Exception { - String errorMsg = null; - - try { - if ((null == aSerializedData) || (null == aKey)) { - Log.e(LOG_TAG, "## deserialize(): invalid input parameters"); - errorMsg = "invalid input parameters"; - } else { - mNativeId = deserializeJni(aSerializedData, aKey); - } - } catch (Exception e) { - Log.e(LOG_TAG, "## deserialize() failed " + e.getMessage()); - errorMsg = e.getMessage(); - } - - if (!TextUtils.isEmpty(errorMsg)) { - releaseSession(); - throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_DESERIALIZATION, errorMsg); - } - } - - /** - * Allocate a new session and initialize it with the serialisation data.<br> - * An exception is thrown if the operation fails. - * @param aSerializedData the session serialisation buffer - * @param aKey the key used to encrypt the serialized account data - * @return the deserialized session - **/ - private native long deserializeJni(byte[] aSerializedData, byte[] aKey); - -} diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkDecryption.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkDecryption.java deleted file mode 100644 index 6a6a22b..0000000 --- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkDecryption.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2018 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. - */ - -package org.matrix.olm; - -import android.util.Log; - -import java.util.Arrays; - -public class OlmPkDecryption { - private static final String LOG_TAG = "OlmPkDecryption"; - - /** Session Id returned by JNI. - * This value uniquely identifies the native session instance. - **/ - private transient long mNativeId; - - public OlmPkDecryption() throws OlmException { - try { - mNativeId = createNewPkDecryptionJni(); - } catch (Exception e) { - throw new OlmException(OlmException.EXCEPTION_CODE_PK_DECRYPTION_CREATION, e.getMessage()); - } - } - - private native long createNewPkDecryptionJni(); - - private native void releasePkDecryptionJni(); - - public void releaseDecryption() { - if (0 != mNativeId) { - releasePkDecryptionJni(); - } - mNativeId = 0; - } - - public boolean isReleased() { - return (0 == mNativeId); - } - - public static native int privateKeyLength(); - - public String setPrivateKey(byte[] privateKey) throws OlmException { - try { - byte[] key = setPrivateKeyJni(privateKey); - return new String(key, "UTF-8"); - } catch (Exception e) { - Log.e(LOG_TAG, "## setPrivateKey(): failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_PK_DECRYPTION_SET_PRIVATE_KEY, e.getMessage()); - } - } - - private native byte[] setPrivateKeyJni(byte[] privateKey); - - public String generateKey() throws OlmException { - try { - byte[] key = generateKeyJni(); - return new String(key, "UTF-8"); - } catch (Exception e) { - Log.e(LOG_TAG, "## setRecipientKey(): failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_PK_DECRYPTION_GENERATE_KEY, e.getMessage()); - } - } - - private native byte[] generateKeyJni(); - - public byte[] privateKey() throws OlmException { - try { - return privateKeyJni(); - } catch (Exception e) { - Log.e(LOG_TAG, "## privateKey(): failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_PK_DECRYPTION_PRIVATE_KEY, e.getMessage()); - } - } - - private native byte[] privateKeyJni(); - - public String decrypt(OlmPkMessage aMessage) throws OlmException { - if (null == aMessage) { - return null; - } - - byte[] plaintextBuffer = decryptJni(aMessage); - try { - String plaintext = new String(plaintextBuffer, "UTF-8"); - return plaintext; - } catch (Exception e) { - Log.e(LOG_TAG, "## pkDecrypt(): failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_PK_DECRYPTION_DECRYPT, e.getMessage()); - } finally { - Arrays.fill(plaintextBuffer, (byte) 0); - } - } - - private native byte[] decryptJni(OlmPkMessage aMessage); -} diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkEncryption.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkEncryption.java deleted file mode 100644 index 01666fd..0000000 --- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkEncryption.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2018 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. - */ - -package org.matrix.olm; - -import android.util.Log; - -import java.util.Arrays; - -public class OlmPkEncryption { - private static final String LOG_TAG = "OlmPkEncryption"; - - /** Session Id returned by JNI. - * This value uniquely identifies the native session instance. - **/ - private transient long mNativeId; - - public OlmPkEncryption() throws OlmException { - try { - mNativeId = createNewPkEncryptionJni(); - } catch (Exception e) { - throw new OlmException(OlmException.EXCEPTION_CODE_PK_ENCRYPTION_CREATION, e.getMessage()); - } - } - - private native long createNewPkEncryptionJni(); - - private native void releasePkEncryptionJni(); - - public void releaseEncryption() { - if (0 != mNativeId) { - releasePkEncryptionJni(); - } - mNativeId = 0; - } - - public boolean isReleased() { - return (0 == mNativeId); - } - - public void setRecipientKey(String aKey) throws OlmException { - if (null == aKey) { - return; - } - - try { - setRecipientKeyJni(aKey.getBytes("UTF-8")); - } catch (Exception e) { - Log.e(LOG_TAG, "## setRecipientKey(): failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_PK_ENCRYPTION_SET_RECIPIENT_KEY, e.getMessage()); - } - } - - private native void setRecipientKeyJni(byte[] aKey); - - public OlmPkMessage encrypt(String aPlaintext) throws OlmException { - if (null == aPlaintext) { - return null; - } - - OlmPkMessage encryptedMsgRetValue = new OlmPkMessage(); - - byte[] plaintextBuffer = null; - try { - plaintextBuffer = aPlaintext.getBytes("UTF-8"); - byte[] ciphertextBuffer = encryptJni(plaintextBuffer, encryptedMsgRetValue); - - if (null != ciphertextBuffer) { - encryptedMsgRetValue.mCipherText = new String(ciphertextBuffer, "UTF-8"); - } - } catch (Exception e) { - Log.e(LOG_TAG, "## pkEncrypt(): failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_PK_ENCRYPTION_ENCRYPT, e.getMessage()); - } finally { - if (null != plaintextBuffer) { - Arrays.fill(plaintextBuffer, (byte) 0); - } - } - - return encryptedMsgRetValue; - } - - private native byte[] encryptJni(byte[] plaintext, OlmPkMessage aMessage); -} diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkMessage.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkMessage.java deleted file mode 100644 index f8a065a..0000000 --- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkMessage.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2018 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. - */ - -package org.matrix.olm; - -public class OlmPkMessage { - public String mCipherText; - public String mMac; - public String mEphemeralKey; -} diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkSigning.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkSigning.java deleted file mode 100644 index 89cb556..0000000 --- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkSigning.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 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. - */ - -package org.matrix.olm; - -import android.util.Log; - -import java.util.Arrays; - -public class OlmPkSigning { - private static final String LOG_TAG = "OlmPkSigning"; - - /** PK Signing Id returned by JNI. - * This value uniquely identifies the native PK signing instance. - **/ - private transient long mNativeId; - - public OlmPkSigning() throws OlmException { - try { - mNativeId = createNewPkSigningJni(); - } catch (Exception e) { - throw new OlmException(OlmException.EXCEPTION_CODE_PK_SIGNING_CREATION, e.getMessage()); - } - } - - private native long createNewPkSigningJni(); - - private native void releasePkSigningJni(); - - public void releaseSigning() { - if (0 != mNativeId) { - releasePkSigningJni(); - } - mNativeId = 0; - } - - public boolean isReleased() { - return (0 == mNativeId); - } - - public static native int seedLength(); - - public static byte[] generateSeed() throws OlmException { - try { - return generateSeedJni(); - } catch (Exception e) { - Log.e(LOG_TAG, "## generateSeed(): failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_PK_SIGNING_GENERATE_SEED, e.getMessage()); - } - } - - public static native byte[] generateSeedJni(); - - public String initWithSeed(byte[] seed) throws OlmException { - try { - byte[] pubKey = setKeyFromSeedJni(seed); - return new String(pubKey, "UTF-8"); - } catch (Exception e) { - Log.e(LOG_TAG, "## initWithSeed(): failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_PK_SIGNING_INIT_WITH_SEED, e.getMessage()); - } - } - - public native byte[] setKeyFromSeedJni(byte[] seed); - - public String sign(String aMessage) throws OlmException { - if (null == aMessage) { - return null; - } - - byte[] messageBuffer = null; - try { - messageBuffer = aMessage.getBytes("UTF-8"); - byte[] signature = pkSignJni(messageBuffer); - return new String(signature, "UTF-8"); - } catch (Exception e) { - Log.e(LOG_TAG, "## pkSign(): failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_PK_SIGNING_SIGN, e.getMessage()); - } finally { - if (null != messageBuffer) { - Arrays.fill(messageBuffer, (byte) 0); - } - } - } - - private native byte[] pkSignJni(byte[] message); -} diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmSAS.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmSAS.java deleted file mode 100644 index a0589e9..0000000 --- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmSAS.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 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. - */ -package org.matrix.olm; - -import android.util.Log; - -import java.io.UnsupportedEncodingException; - -public class OlmSAS { - - private static final String LOG_TAG = OlmSAS.class.getName(); - /** - * Session Id returned by JNI. - * This value uniquely identifies the native SAS instance. - **/ - private transient long mNativeId; - - private String theirPublicKey = null; - - public OlmSAS() throws OlmException { - try { - mNativeId = createNewSASJni(); - } catch (Exception e) { - throw new OlmException(OlmException.EXCEPTION_CODE_SAS_CREATION, e.getMessage()); - } - } - - /** - * Gets the Public Key encoded in Base64 with no padding - * @return The public key - * @throws OlmException the failure reason - */ - public String getPublicKey() throws OlmException { - try { - byte[] buffer = getPubKeyJni(); - - if (null != buffer) { - return new String(buffer, "UTF-8"); - } - } catch (Exception e) { - Log.e(LOG_TAG, "## sessionIdentifier(): " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_SAS_ERROR, e.getMessage()); - } - - return null; - } - - /** - * Sets the public key of other user. - * - * @param otherPkey other user public key (base64 encoded with no padding) - * @throws OlmException the failure reason - */ - public void setTheirPublicKey(String otherPkey) throws OlmException { - try { - setTheirPubKey(otherPkey.getBytes("UTF-8")); - } catch (UnsupportedEncodingException e) { - throw new OlmException(OlmException.EXCEPTION_CODE_SAS_ERROR, e.getMessage()); - } - this.theirPublicKey = otherPkey; - } - - - /** - * Generate bytes to use for the short authentication string. - * - * @param info info extra information to mix in when generating the bytes, as - * per the Matrix spec. - * @param byteNumber The size of the short code to generate - * @return The generated shortcode - * @throws OlmException the failure reason - */ - public byte[] generateShortCode(String info, int byteNumber) throws OlmException { - if (theirPublicKey == null || theirPublicKey.isEmpty()) { - throw new OlmException(OlmException.EXCEPTION_CODE_SAS_MISSING_THEIR_PKEY, "call setTheirPublicKey first"); - } - try { - return generateShortCodeJni(info.getBytes("UTF-8"), byteNumber); - } catch (Exception e) { - Log.e(LOG_TAG, "## sessionIdentifier(): " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_SAS_GENERATE_SHORT_CODE, e.getMessage()); - } - } - - - public String calculateMac(String message, String info) throws OlmException { - try { - byte[] bytes = calculateMacJni(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 { - try { - byte[] bytes = calculateMacLongKdfJni(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; - } - - /** - * Create an OLM session in native side.<br> - * Do not forget to call {@link #releaseSASJni()} when JAVA side is done. - * - * @return native account instance identifier or throw an exception. - */ - private native long createNewSASJni(); - - /** - * Destroy the corresponding OLM session native object.<br> - * This method must ALWAYS be called when this JAVA instance - * is destroyed (ie. garbage collected) to prevent memory leak in native side. - * See {@link #createNewSASJni()}. - */ - private native void releaseSASJni(); - - private native byte[] getPubKeyJni(); - - private native void setTheirPubKey(byte[] pubKey); - - private native byte[] generateShortCodeJni(byte[] info, int byteNumber); - - private native byte[] calculateMacJni(byte[] message, byte[] info); - - private native byte[] calculateMacLongKdfJni(byte[] message, byte[] info); - - /** - * Release native session and invalid its JAVA reference counter part.<br> - * Public API for {@link #releaseSASJni()}. - */ - public void releaseSas() { - if (0 != mNativeId) { - releaseSASJni(); - } - mNativeId = 0; - } -} diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java deleted file mode 100644 index 3c5ce49..0000000 --- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java +++ /dev/null @@ -1,452 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016 Vector Creations 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. - */ - -package org.matrix.olm; - -import android.text.TextUtils; -import android.util.Log; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; - -import java.util.Arrays; - -/** - * Session class used to create Olm sessions in conjunction with {@link OlmAccount} class.<br> - * Olm session is used to encrypt data between devices, especially to create Olm group sessions (see {@link OlmOutboundGroupSession} and {@link OlmInboundGroupSession}).<br> - * To establish an Olm session with Bob, Alice calls {@link #initOutboundSession(OlmAccount, String, String)} with Bob's identity and onetime keys. Then Alice generates an encrypted PRE_KEY message ({@link #encryptMessage(String)}) - * used by Bob to open the Olm session in his side with {@link #initOutboundSession(OlmAccount, String, String)}. - * From this step on, messages can be exchanged by using {@link #encryptMessage(String)} and {@link #decryptMessage(OlmMessage)}. - * <br><br>Detailed implementation guide is available at <a href="http://matrix.org/docs/guides/e2e_implementation.html">Implementing End-to-End Encryption in Matrix clients</a>. - */ -public class OlmSession extends CommonSerializeUtils implements Serializable { - private static final long serialVersionUID = -8975488639186976419L; - private static final String LOG_TAG = "OlmSession"; - - /** Session Id returned by JNI. - * This value uniquely identifies the native session instance. - **/ - private transient long mNativeId; - - public OlmSession() throws OlmException { - try { - mNativeId = createNewSessionJni(); - } catch (Exception e) { - throw new OlmException(OlmException.EXCEPTION_CODE_INIT_SESSION_CREATION, e.getMessage()); - } - } - - /** - * Create an OLM session in native side.<br> - * Do not forget to call {@link #releaseSession()} when JAVA side is done. - * @return native account instance identifier or throw an exception. - */ - private native long createNewSessionJni(); - - /** - * Getter on the session ID. - * @return native session ID - */ - long getOlmSessionId(){ - return mNativeId; - } - - /** - * Destroy the corresponding OLM session native object.<br> - * This method must ALWAYS be called when this JAVA instance - * is destroyed (ie. garbage collected) to prevent memory leak in native side. - * See {@link #createNewSessionJni()}. - */ - private native void releaseSessionJni(); - - /** - * Release native session and invalid its JAVA reference counter part.<br> - * Public API for {@link #releaseSessionJni()}. - */ - public void releaseSession() { - if (0 != mNativeId) { - releaseSessionJni(); - } - mNativeId = 0; - } - - /** - * Return true the object resources have been released.<br> - * @return true the object resources have been released - */ - public boolean isReleased() { - return (0 == mNativeId); - } - - /** - * Creates a new out-bound session for sending messages to a recipient - * identified by an identity key and a one time key.<br> - * @param aAccount the account to associate with this session - * @param aTheirIdentityKey the identity key of the recipient - * @param aTheirOneTimeKey the one time key of the recipient - * @exception OlmException the failure reason - */ - public void initOutboundSession(OlmAccount aAccount, String aTheirIdentityKey, String aTheirOneTimeKey) throws OlmException { - if ((null == aAccount) || TextUtils.isEmpty(aTheirIdentityKey) || TextUtils.isEmpty(aTheirOneTimeKey)) { - Log.e(LOG_TAG, "## initOutboundSession(): invalid input parameters"); - throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_INIT_OUTBOUND_SESSION, "invalid input parameters"); - } else { - try { - initOutboundSessionJni(aAccount.getOlmAccountId(), aTheirIdentityKey.getBytes("UTF-8"), aTheirOneTimeKey.getBytes("UTF-8")); - } catch (Exception e) { - Log.e(LOG_TAG, "## initOutboundSession(): " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_INIT_OUTBOUND_SESSION, e.getMessage()); - } - } - } - - /** - * Create a new in-bound session for sending/receiving messages from an - * incoming PRE_KEY message.<br> The recipient is defined as the entity - * with whom the session is established. - * An exception is thrown if the operation fails. - * @param aOlmAccountId account instance - * @param aTheirIdentityKey the identity key of the recipient - * @param aTheirOneTimeKey the one time key of the recipient - **/ - private native void initOutboundSessionJni(long aOlmAccountId, byte[] aTheirIdentityKey, byte[] aTheirOneTimeKey); - - /** - * Create a new in-bound session for sending/receiving messages from an - * incoming PRE_KEY message ({@link OlmMessage#MESSAGE_TYPE_PRE_KEY}).<br> - * This API may be used to process a "m.room.encrypted" event when type = 1 (PRE_KEY). - * @param aAccount the account to associate with this session - * @param aPreKeyMsg PRE KEY message - * @exception OlmException the failure reason - */ - public void initInboundSession(OlmAccount aAccount, String aPreKeyMsg) throws OlmException { - if ((null == aAccount) || TextUtils.isEmpty(aPreKeyMsg)){ - Log.e(LOG_TAG, "## initInboundSession(): invalid input parameters"); - throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_INIT_INBOUND_SESSION, "invalid input parameters"); - } else { - try { - initInboundSessionJni(aAccount.getOlmAccountId(), aPreKeyMsg.getBytes("UTF-8")); - } catch (Exception e) { - Log.e(LOG_TAG, "## initInboundSession(): " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_INIT_INBOUND_SESSION, e.getMessage()); - } - } - } - - /** - * Create a new in-bound session for sending/receiving messages from an - * incoming PRE_KEY message.<br> - * An exception is thrown if the operation fails. - * @param aOlmAccountId account instance - * @param aOneTimeKeyMsg PRE_KEY message - */ - private native void initInboundSessionJni(long aOlmAccountId, byte[] aOneTimeKeyMsg); - - /** - * Create a new in-bound session for sending/receiving messages from an - * incoming PRE_KEY({@link OlmMessage#MESSAGE_TYPE_PRE_KEY}) message based on the sender identity key.<br> - * Public API for {@link #initInboundSessionFromIdKeyJni(long, byte[], byte[])}. - * This API may be used to process a "m.room.encrypted" event when type = 1 (PRE_KEY). - * This method must only be called the first time a pre-key message is received from an inbound session. - * @param aAccount the account to associate with this session - * @param aTheirIdentityKey the sender identity key - * @param aPreKeyMsg PRE KEY message - * @exception OlmException the failure reason - */ - public void initInboundSessionFrom(OlmAccount aAccount, String aTheirIdentityKey, String aPreKeyMsg) throws OlmException { - if ( (null==aAccount) || TextUtils.isEmpty(aPreKeyMsg)){ - Log.e(LOG_TAG, "## initInboundSessionFrom(): invalid input parameters"); - throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_INIT_INBOUND_SESSION_FROM, "invalid input parameters"); - } else { - try { - initInboundSessionFromIdKeyJni(aAccount.getOlmAccountId(), aTheirIdentityKey.getBytes("UTF-8"), aPreKeyMsg.getBytes("UTF-8")); - } catch (Exception e) { - Log.e(LOG_TAG, "## initInboundSessionFrom(): " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_INIT_INBOUND_SESSION_FROM, e.getMessage()); - } - } - } - - /** - * Create a new in-bound session for sending/receiving messages from an - * incoming PRE_KEY message based on the recipient identity key.<br> - * An exception is thrown if the operation fails. - * @param aOlmAccountId account instance - * @param aTheirIdentityKey the identity key of the recipient - * @param aOneTimeKeyMsg encrypted message - */ - private native void initInboundSessionFromIdKeyJni(long aOlmAccountId, byte[] aTheirIdentityKey, byte[] aOneTimeKeyMsg); - - /** - * Get the session identifier.<br> Will be the same for both ends of the - * conversation. The session identifier is returned as a String object. - * Session Id sample: "session_id":"M4fOVwD6AABrkTKl" - * Public API for {@link #getSessionIdentifierJni()}. - * @return the session ID - * @exception OlmException the failure reason - */ - public String sessionIdentifier() throws OlmException { - try { - byte[] buffer = getSessionIdentifierJni(); - - if (null != buffer) { - return new String(buffer, "UTF-8"); - } - } catch (Exception e) { - Log.e(LOG_TAG, "## sessionIdentifier(): " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_SESSION_IDENTIFIER, e.getMessage()); - } - - return null; - } - - /** - * Get the session identifier for this session. - * An exception is thrown if the operation fails. - * @return the session identifier - */ - private native byte[] getSessionIdentifierJni(); - - /** - * 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). - * Public API for {@link #matchesInboundSessionJni(byte[])}. - * @param aOneTimeKeyMsg PRE KEY message - * @return true if the one time key matches. - */ - public boolean matchesInboundSession(String aOneTimeKeyMsg) { - boolean retCode = false; - - try { - retCode = matchesInboundSessionJni(aOneTimeKeyMsg.getBytes("UTF-8")); - } catch (Exception e) { - Log.e(LOG_TAG, "## matchesInboundSession(): failed " + e.getMessage()); - } - - return retCode; - } - - /** - * Checks if the 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). - * An exception is thrown if the operation fails. - * @param aOneTimeKeyMsg PRE KEY message - * @return true if the PRE_KEY message matches - */ - private native boolean matchesInboundSessionJni(byte[] aOneTimeKeyMsg); - - /** - * Checks if the PRE_KEY({@link OlmMessage#MESSAGE_TYPE_PRE_KEY}) message is for this in-bound session based on the sender identity key.<br> - * This API may be used to process a "m.room.encrypted" event when type = 1 (PRE_KEY). - * Public API for {@link #matchesInboundSessionJni(byte[])}. - * @param aTheirIdentityKey the sender identity key - * @param aOneTimeKeyMsg PRE KEY message - * @return this if operation succeed, null otherwise - */ - public boolean matchesInboundSessionFrom(String aTheirIdentityKey, String aOneTimeKeyMsg) { - boolean retCode = false; - - try { - retCode = matchesInboundSessionFromIdKeyJni(aTheirIdentityKey.getBytes("UTF-8"), aOneTimeKeyMsg.getBytes("UTF-8")); - } catch (Exception e) { - Log.e(LOG_TAG, "## matchesInboundSessionFrom(): failed " + e.getMessage()); - } - - return retCode; - } - - /** - * Checks if the PRE_KEY message is for this in-bound session based on the sender identity key.<br> - * This API may be used to process a "m.room.encrypted" event when type = 1 (PRE_KEY). - * An exception is thrown if the operation fails. - * @param aTheirIdentityKey the identity key of the sender - * @param aOneTimeKeyMsg PRE KEY message - * @return true if the PRE_KEY message matches. - */ - private native boolean matchesInboundSessionFromIdKeyJni(byte[] aTheirIdentityKey, byte[] aOneTimeKeyMsg); - - /** - * Encrypt a message using the session.<br> - * The encrypted message is returned in a OlmMessage object. - * Public API for {@link #encryptMessageJni(byte[], OlmMessage)}. - * @param aClearMsg message to encrypted - * @return the encrypted message - * @exception OlmException the failure reason - */ - public OlmMessage encryptMessage(String aClearMsg) throws OlmException { - if (null == aClearMsg) { - return null; - } - - OlmMessage encryptedMsgRetValue = new OlmMessage(); - - try { - byte[] clearMsgBuffer = aClearMsg.getBytes("UTF-8"); - byte[] encryptedMessageBuffer = encryptMessageJni(clearMsgBuffer, encryptedMsgRetValue); - Arrays.fill(clearMsgBuffer, (byte) 0); - - if (null != encryptedMessageBuffer) { - encryptedMsgRetValue.mCipherText = new String(encryptedMessageBuffer, "UTF-8"); - } - } catch (Exception e) { - Log.e(LOG_TAG, "## encryptMessage(): failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_ENCRYPT_MESSAGE, e.getMessage()); - } - - return encryptedMsgRetValue; - } - - /** - * Encrypt a message using the session.<br> - * An exception is thrown if the operation fails. - * @param aClearMsg clear text message - * @param aEncryptedMsg ciphered message - * @return the encrypted message - */ - private native byte[] encryptMessageJni(byte[] aClearMsg, OlmMessage aEncryptedMsg); - - /** - * Decrypt a message using the session.<br> - * The encrypted message is given as a OlmMessage object. - * @param aEncryptedMsg message to decrypt - * @return the decrypted message - * @exception OlmException the failure reason - */ - public String decryptMessage(OlmMessage aEncryptedMsg) throws OlmException { - if (null == aEncryptedMsg) { - return null; - } - - try { - byte[] plaintextBuffer = decryptMessageJni(aEncryptedMsg); - String plaintext = new String(plaintextBuffer, "UTF-8"); - Arrays.fill(plaintextBuffer, (byte) 0); - return plaintext; - } catch (Exception e) { - Log.e(LOG_TAG, "## decryptMessage(): failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_DECRYPT_MESSAGE, e.getMessage()); - } - } - /** - * Decrypt a message using the session.<br> - * An exception is thrown if the operation fails. - * @param aEncryptedMsg message to decrypt - * @return the decrypted message - */ - private native byte[] decryptMessageJni(OlmMessage aEncryptedMsg); - - //============================================================================================================== - // Serialization management - //============================================================================================================== - - /** - * Kick off the serialization mechanism. - * @param aOutStream output stream for serializing - * @throws IOException exception - */ - private void writeObject(ObjectOutputStream aOutStream) throws IOException { - serialize(aOutStream); - } - - /** - * Kick off the deserialization mechanism. - * @param aInStream input stream - * @throws IOException exception - * @throws ClassNotFoundException exception - */ - private void readObject(ObjectInputStream aInStream) throws Exception { - deserialize(aInStream); - } - - /** - * Return a session 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 session as a bytes buffer - */ - @Override - protected byte[] serialize(byte[] aKey, StringBuffer aErrorMsg) { - byte[] pickleRetValue = null; - - // sanity check - if(null == aErrorMsg) { - Log.e(LOG_TAG,"## serializeDataWithKey(): invalid parameter - aErrorMsg=null"); - } else if (null == aKey) { - aErrorMsg.append("Invalid input parameters in serializeDataWithKey()"); - } else { - aErrorMsg.setLength(0); - try { - pickleRetValue = serializeJni(aKey); - } catch (Exception e) { - Log.e(LOG_TAG,"## serializeDataWithKey(): failed " + e.getMessage()); - aErrorMsg.append(e.getMessage()); - } - } - - return pickleRetValue; - } - - /** - * Serialize and encrypt session instance.<br> - * An exception is thrown if the operation fails. - * @param aKeyBuffer key used to encrypt the serialized account data - * @return the serialised account as bytes buffer. - **/ - private native byte[] serializeJni(byte[] aKeyBuffer); - - /** - * Loads an account from a pickled base64 string.<br> - * See {@link #serialize(byte[], StringBuffer)} - * @param aSerializedData pickled account in a base64 string format - * @param aKey key used to encrypted - */ - @Override - protected void deserialize(byte[] aSerializedData, byte[] aKey) throws Exception { - String errorMsg = null; - - try { - if ((null == aSerializedData) || (null == aKey)) { - Log.e(LOG_TAG, "## deserialize(): invalid input parameters"); - errorMsg = "invalid input parameters"; - } else { - mNativeId = deserializeJni(aSerializedData, aKey); - } - } catch (Exception e) { - Log.e(LOG_TAG, "## deserialize() failed " + e.getMessage()); - errorMsg = e.getMessage(); - } - - if (!TextUtils.isEmpty(errorMsg)) { - releaseSession(); - throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_DESERIALIZATION, errorMsg); - } - } - /** - * Allocate a new session and initialize it with the serialisation data.<br> - * An exception is thrown if the operation fails. - * @param aSerializedData the session serialisation buffer - * @param aKey the key used to encrypt the serialized account data - * @return the deserialized session - **/ - private native long deserializeJni(byte[] aSerializedData, byte[] aKey); -} - diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmUtility.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmUtility.java deleted file mode 100644 index 250cfb1..0000000 --- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmUtility.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright 2017 OpenMarket Ltd - * Copyright 2017 Vector Creations 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. - */ - -package org.matrix.olm; - -import android.text.TextUtils; -import android.util.Log; - -import org.json.JSONObject; - -import java.security.SecureRandom; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -/** - * Olm SDK helper class. - */ -public class OlmUtility { - private static final String LOG_TAG = "OlmUtility"; - - public static final int RANDOM_KEY_SIZE = 32; - - /** Instance Id returned by JNI. - * This value uniquely identifies this utility instance. - **/ - private long mNativeId; - - public OlmUtility() throws OlmException { - initUtility(); - } - - /** - * Create a native utility instance. - * To be called before any other API call. - * @exception OlmException the exception - */ - private void initUtility() throws OlmException { - try { - mNativeId = createUtilityJni(); - } catch (Exception e) { - throw new OlmException(OlmException.EXCEPTION_CODE_UTILITY_CREATION, e.getMessage()); - } - } - - private native long createUtilityJni(); - - /** - * Release native instance.<br> - * Public API for {@link #releaseUtilityJni()}. - */ - public void releaseUtility() { - if (0 != mNativeId) { - releaseUtilityJni(); - } - mNativeId = 0; - } - private native void releaseUtilityJni(); - - /** - * Verify an ed25519 signature.<br> - * An exception is thrown if the operation fails. - * @param aSignature the base64-encoded message signature to be checked. - * @param aFingerprintKey the ed25519 key (fingerprint key) - * @param aMessage the signed message - * @exception OlmException the failure reason - */ - public void verifyEd25519Signature(String aSignature, String aFingerprintKey, String aMessage) throws OlmException { - String errorMessage; - byte[] messageBuffer = null; - - try { - if (TextUtils.isEmpty(aSignature) || TextUtils.isEmpty(aFingerprintKey) || TextUtils.isEmpty(aMessage)) { - Log.e(LOG_TAG, "## verifyEd25519Signature(): invalid input parameters"); - errorMessage = "JAVA sanity check failure - invalid input parameters"; - } else { - messageBuffer = aMessage.getBytes("UTF-8"); - errorMessage = verifyEd25519SignatureJni(aSignature.getBytes("UTF-8"), aFingerprintKey.getBytes("UTF-8"), messageBuffer); - } - } catch (Exception e) { - Log.e(LOG_TAG, "## verifyEd25519Signature(): failed " + e.getMessage()); - errorMessage = e.getMessage(); - } finally { - if (messageBuffer != null) { - Arrays.fill(messageBuffer, (byte) 0); - } - } - - if (!TextUtils.isEmpty(errorMessage)) { - throw new OlmException(OlmException.EXCEPTION_CODE_UTILITY_VERIFY_SIGNATURE, errorMessage); - } - } - - /** - * Verify an ed25519 signature. - * Return a human readable error message in case of verification failure. - * @param aSignature the base64-encoded message signature to be checked. - * @param aFingerprintKey the ed25519 key - * @param aMessage the signed message - * @return null if validation succeed, the error message string if operation failed - */ - private native String verifyEd25519SignatureJni(byte[] aSignature, byte[] aFingerprintKey, byte[] aMessage); - - /** - * Compute the hash(SHA-256) value of the string given in parameter(aMessageToHash).<br> - * The hash value is the returned by the method. - * @param aMessageToHash message to be hashed - * @return hash value if operation succeed, null otherwise - */ - public String sha256(String aMessageToHash) { - String hashRetValue = null; - - if (null != aMessageToHash) { - byte[] messageBuffer = null; - try { - messageBuffer = aMessageToHash.getBytes("UTF-8"); - hashRetValue = new String(sha256Jni(messageBuffer), "UTF-8"); - } catch (Exception e) { - Log.e(LOG_TAG, "## sha256(): failed " + e.getMessage()); - } finally { - if (null != messageBuffer) { - Arrays.fill(messageBuffer, (byte) 0); - } - } - } - - return hashRetValue; - } - - /** - * Compute the digest (SHA 256) for the message passed in parameter.<br> - * The digest value is the function return value. - * An exception is thrown if the operation fails. - * @param aMessage the message - * @return digest of the message. - **/ - private native byte[] sha256Jni(byte[] aMessage); - - /** - * Helper method to compute a string based on random integers. - * @return bytes buffer containing randoms integer values - */ - public static byte[] getRandomKey() { - SecureRandom secureRandom = new SecureRandom(); - byte[] buffer = new byte[RANDOM_KEY_SIZE]; - secureRandom.nextBytes(buffer); - - // the key is saved as string - // so avoid the UTF8 marker bytes - for(int i = 0; i < RANDOM_KEY_SIZE; i++) { - buffer[i] = (byte)(buffer[i] & 0x7F); - } - return buffer; - } - - /** - * Return true the object resources have been released.<br> - * @return true the object resources have been released - */ - public boolean isReleased() { - return (0 == mNativeId); - } - - /** - * Build a string-string dictionary from a jsonObject.<br> - * @param jsonObject the object to parse - * @return the map - */ - public static Map<String, String> toStringMap(JSONObject jsonObject) { - if (null != jsonObject) { - HashMap<String, String> map = new HashMap<>(); - Iterator<String> keysItr = jsonObject.keys(); - while(keysItr.hasNext()) { - String key = keysItr.next(); - try { - Object value = jsonObject.get(key); - - if (value instanceof String) { - map.put(key, (String) value); - } else { - Log.e(LOG_TAG, "## toStringMap(): unexpected type " + value.getClass()); - } - } catch (Exception e) { - Log.e(LOG_TAG, "## toStringMap(): failed " + e.getMessage()); - } - } - - return map; - } - - return null; - } - - /** - * Build a string-string dictionary of string dictionary from a jsonObject.<br> - * @param jsonObject the object to parse - * @return the map - */ - public static Map<String, Map<String, String>> toStringMapMap(JSONObject jsonObject) { - if (null != jsonObject) { - HashMap<String, Map<String, String>> map = new HashMap<>(); - - Iterator<String> keysItr = jsonObject.keys(); - while(keysItr.hasNext()) { - String key = keysItr.next(); - try { - Object value = jsonObject.get(key); - - if (value instanceof JSONObject) { - map.put(key, toStringMap((JSONObject) value)); - } else { - Log.e(LOG_TAG, "## toStringMapMap(): unexpected type " + value.getClass()); - } - } catch (Exception e) { - Log.e(LOG_TAG, "## toStringMapMap(): failed " + e.getMessage()); - } - } - - return map; - } - - return null; - } -} - diff --git a/android/olm-sdk/src/main/jni/Android.mk b/android/olm-sdk/src/main/jni/Android.mk deleted file mode 100644 index 101346b..0000000 --- a/android/olm-sdk/src/main/jni/Android.mk +++ /dev/null @@ -1,67 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - - -LOCAL_MODULE := olm - -SRC_ROOT_DIR := ../../../../.. - -include $(LOCAL_PATH)/$(SRC_ROOT_DIR)/common.mk -OLM_VERSION := $(MAJOR).$(MINOR).$(PATCH) - -$(info LOCAL_PATH=$(LOCAL_PATH)) -$(info SRC_ROOT_DIR=$(SRC_ROOT_DIR)) -$(info OLM_VERSION=$(OLM_VERSION)) - -LOCAL_CPPFLAGS+= -std=c++11 -Wall -LOCAL_CONLYFLAGS+= -std=c99 -LOCAL_CFLAGS+= -DOLMLIB_VERSION_MAJOR=$(MAJOR) \ --DOLMLIB_VERSION_MINOR=$(MINOR) \ --DOLMLIB_VERSION_PATCH=$(PATCH) - -#LOCAL_CFLAGS+= -DNDK_DEBUG - -LOCAL_CFLAGS+=-fstack-protector-all -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Wall -LOCAL_LDFLAGS=-z relro -z now - -LOCAL_C_INCLUDES+= $(LOCAL_PATH)/$(SRC_ROOT_DIR)/include/ \ -$(LOCAL_PATH)/$(SRC_ROOT_DIR)/lib - -$(info LOCAL_C_INCLUDES=$(LOCAL_C_INCLUDES)) - -LOCAL_SRC_FILES := $(SRC_ROOT_DIR)/src/account.cpp \ -$(SRC_ROOT_DIR)/src/base64.cpp \ -$(SRC_ROOT_DIR)/src/cipher.cpp \ -$(SRC_ROOT_DIR)/src/crypto.cpp \ -$(SRC_ROOT_DIR)/src/memory.cpp \ -$(SRC_ROOT_DIR)/src/message.cpp \ -$(SRC_ROOT_DIR)/src/olm.cpp \ -$(SRC_ROOT_DIR)/src/pickle.cpp \ -$(SRC_ROOT_DIR)/src/ratchet.cpp \ -$(SRC_ROOT_DIR)/src/session.cpp \ -$(SRC_ROOT_DIR)/src/utility.cpp \ -$(SRC_ROOT_DIR)/src/pk.cpp \ -$(SRC_ROOT_DIR)/src/sas.c \ -$(SRC_ROOT_DIR)/src/ed25519.c \ -$(SRC_ROOT_DIR)/src/error.c \ -$(SRC_ROOT_DIR)/src/inbound_group_session.c \ -$(SRC_ROOT_DIR)/src/megolm.c \ -$(SRC_ROOT_DIR)/src/outbound_group_session.c \ -$(SRC_ROOT_DIR)/src/pickle_encoding.c \ -$(SRC_ROOT_DIR)/lib/crypto-algorithms/sha256.c \ -$(SRC_ROOT_DIR)/lib/crypto-algorithms/aes.c \ -$(SRC_ROOT_DIR)/lib/curve25519-donna/curve25519-donna.c \ -olm_account.cpp \ -olm_session.cpp \ -olm_jni_helper.cpp \ -olm_inbound_group_session.cpp \ -olm_outbound_group_session.cpp \ -olm_utility.cpp \ -olm_manager.cpp \ -olm_pk.cpp \ -olm_sas.cpp - -LOCAL_LDLIBS := -llog - -include $(BUILD_SHARED_LIBRARY) - diff --git a/android/olm-sdk/src/main/jni/Application.mk b/android/olm-sdk/src/main/jni/Application.mk deleted file mode 100644 index e052911..0000000 --- a/android/olm-sdk/src/main/jni/Application.mk +++ /dev/null @@ -1,3 +0,0 @@ -APP_PLATFORM := android-16 -APP_ABI := arm64-v8a armeabi-v7a x86_64 x86 -APP_STL := c++_static
\ No newline at end of file diff --git a/android/olm-sdk/src/main/jni/olm_account.cpp b/android/olm-sdk/src/main/jni/olm_account.cpp deleted file mode 100644 index 00b1460..0000000 --- a/android/olm-sdk/src/main/jni/olm_account.cpp +++ /dev/null @@ -1,695 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016 Vector Creations 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. - */ - -#include "olm_account.h" - -using namespace AndroidOlmSdk; - -/** - * Init memory allocation for account creation. - * @return valid memory allocation, NULL otherwise - **/ -OlmAccount* initializeAccountMemory() -{ - size_t accountSize = olm_account_size(); - OlmAccount* accountPtr = (OlmAccount*)malloc(accountSize); - - if (accountPtr) - { - // init account object - accountPtr = olm_account(accountPtr); - LOGD("## initializeAccountMemory(): success - OLM account size=%lu",static_cast<long unsigned int>(accountSize)); - } - else - { - LOGE("## initializeAccountMemory(): failure - OOM"); - } - - return accountPtr; -} - -/** - * Create a new account and return it to JAVA side.<br> - * Since a C prt is returned as a jlong, special care will be taken - * to make the cast (OlmAccount* => jlong) platform independent. - * @return the initialized OlmAccount* instance or throw an exception if fails - **/ -JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(createNewAccountJni)(JNIEnv *env, jobject thiz) -{ - const char* errorMessage = NULL; - OlmAccount *accountPtr = initializeAccountMemory(); - - // init account memory allocation - if (!accountPtr) - { - LOGE("## initNewAccount(): failure - init account OOM"); - errorMessage = "init account OOM"; - } - else - { - // get random buffer size - size_t randomSize = olm_create_account_random_length(accountPtr); - - LOGD("## initNewAccount(): randomSize=%lu", static_cast<long unsigned int>(randomSize)); - - uint8_t *randomBuffPtr = NULL; - size_t accountRetCode; - - // allocate random buffer - if ((0 != randomSize) && !setRandomInBuffer(env, &randomBuffPtr, randomSize)) - { - LOGE("## initNewAccount(): failure - random buffer init"); - errorMessage = "random buffer init"; - } - else - { - // create account - accountRetCode = olm_create_account(accountPtr, (void*)randomBuffPtr, randomSize); - - if (accountRetCode == olm_error()) - { - LOGE("## initNewAccount(): failure - account creation failed Msg=%s", olm_account_last_error(accountPtr)); - errorMessage = olm_account_last_error(accountPtr); - } - - LOGD("## initNewAccount(): success - OLM account created"); - LOGD("## initNewAccount(): success - accountPtr=%p (jlong)(intptr_t)accountPtr=%lld",accountPtr,(jlong)(intptr_t)accountPtr); - } - - if (randomBuffPtr) - { - memset(randomBuffPtr, 0, randomSize); - free(randomBuffPtr); - } - } - - if (errorMessage) - { - // release the allocated data - if (accountPtr) - { - olm_clear_account(accountPtr); - free(accountPtr); - } - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return (jlong)(intptr_t)accountPtr; -} -/** - * Release the account allocation made by initializeAccountMemory().<br> - * This method MUST be called when java counter part account instance is done. - */ -JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(releaseAccountJni)(JNIEnv *env, jobject thiz) -{ - LOGD("## releaseAccountJni(): IN"); - - OlmAccount* accountPtr = getAccountInstanceId(env, thiz); - - if (!accountPtr) - { - LOGE(" ## releaseAccountJni(): failure - invalid Account ptr=NULL"); - } - else - { - LOGD(" ## releaseAccountJni(): accountPtr=%p",accountPtr); - olm_clear_account(accountPtr); - - LOGD(" ## releaseAccountJni(): IN"); - // even if free(NULL) does not crash, logs are performed for debug purpose - free(accountPtr); - LOGD(" ## releaseAccountJni(): OUT"); - } -} - -// ********************************************************************* -// ************************* IDENTITY KEYS API ************************* -// ********************************************************************* - -/** - * Get identity keys: Ed25519 fingerprint key and Curve25519 identity key.<br> - * The keys are returned in the byte array. - * @return the identity keys or throw an exception if it fails - **/ -JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(identityKeysJni)(JNIEnv *env, jobject thiz) -{ - const char* errorMessage = NULL; - jbyteArray byteArrayRetValue = NULL; - OlmAccount* accountPtr = getAccountInstanceId(env, thiz); - - if (!accountPtr) - { - LOGE("## identityKeys(): failure - invalid Account ptr=NULL"); - errorMessage = "invalid Account ptr"; - } - else - { - LOGD("## identityKeys(): accountPtr =%p", accountPtr); - - // identity keys allocation - size_t identityKeysLength = olm_account_identity_keys_length(accountPtr); - uint8_t *identityKeysBytesPtr = (uint8_t*)malloc(identityKeysLength); - - if (!identityKeysBytesPtr) - { - LOGE("## identityKeys(): failure - identity keys array OOM"); - errorMessage = "identity keys array OOM"; - } - else - { - // retrieve key pairs in identityKeysBytesPtr - size_t keysResult = olm_account_identity_keys(accountPtr, identityKeysBytesPtr, identityKeysLength); - - if (keysResult == olm_error()) - { - errorMessage = (const char *)olm_account_last_error(accountPtr); - LOGE("## identityKeys(): failure - error getting identity keys Msg=%s", errorMessage); - } - else - { - // allocate the byte array to be returned to java - byteArrayRetValue = env->NewByteArray(identityKeysLength); - - if (!byteArrayRetValue) - { - LOGE("## identityKeys(): failure - return byte array OOM"); - errorMessage = "byte array OOM"; - } - else - { - env->SetByteArrayRegion(byteArrayRetValue, 0/*offset*/, identityKeysLength, (const jbyte*)identityKeysBytesPtr); - LOGD("## identityKeys(): success - result=%lu", static_cast<long unsigned int>(keysResult)); - } - } - - free(identityKeysBytesPtr); - } - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return byteArrayRetValue; -} - -// ********************************************************************* -// ************************* ONE TIME KEYS API ************************* -// ********************************************************************* - -/** - * 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 - * <tt>curve25519</tt>, which is itself an object mapping key id to - * base64-encoded Curve25519 key.<br> - * @return byte array containing the one time keys or throw an exception if it fails - */ -JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(maxOneTimeKeysJni)(JNIEnv *env, jobject thiz) -{ - OlmAccount* accountPtr = getAccountInstanceId(env, thiz); - size_t maxKeys = -1; - - if (!accountPtr) - { - LOGE("## maxOneTimeKey(): failure - invalid Account ptr=NULL"); - } - else - { - maxKeys = olm_account_max_number_of_one_time_keys(accountPtr); - } - - LOGD("## maxOneTimeKey(): Max keys=%lu", static_cast<long unsigned int>(maxKeys)); - - return (jlong)maxKeys; -} - -/** - * Generate "one time keys". - * An exception is thrown if the operation fails. - * @param aNumberOfKeys number of keys to generate - **/ -JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(generateOneTimeKeysJni)(JNIEnv *env, jobject thiz, jint aNumberOfKeys) -{ - const char* errorMessage = NULL; - OlmAccount *accountPtr = getAccountInstanceId(env, thiz); - - if (!accountPtr) - { - LOGE("## generateOneTimeKeysJni(): failure - invalid Account ptr"); - errorMessage = "invalid Account ptr"; - } - else - { - // keys memory allocation - size_t randomLength = olm_account_generate_one_time_keys_random_length(accountPtr, (size_t)aNumberOfKeys); - LOGD("## generateOneTimeKeysJni(): randomLength=%lu", static_cast<long unsigned int>(randomLength)); - - uint8_t *randomBufferPtr = NULL; - - if ((0 != randomLength) && !setRandomInBuffer(env, &randomBufferPtr, randomLength)) - { - LOGE("## generateOneTimeKeysJni(): failure - random buffer init"); - errorMessage = "random buffer init"; - } - else - { - LOGD("## generateOneTimeKeysJni(): accountPtr =%p aNumberOfKeys=%d",accountPtr, aNumberOfKeys); - - // retrieve key pairs in keysBytesPtr - size_t result = olm_account_generate_one_time_keys(accountPtr, (size_t)aNumberOfKeys, (void*)randomBufferPtr, randomLength); - - if (result == olm_error()) - { - errorMessage = olm_account_last_error(accountPtr); - LOGE("## generateOneTimeKeysJni(): failure - error generating one time keys Msg=%s", errorMessage); - } - else - { - LOGD("## generateOneTimeKeysJni(): 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 "one time keys".<br> - * Return the public parts of the unpublished "one time keys" for the account - * @return a valid byte array if operation succeed, null otherwise - **/ -JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(oneTimeKeysJni)(JNIEnv *env, jobject thiz) -{ - const char* errorMessage = NULL; - jbyteArray byteArrayRetValue = NULL; - OlmAccount* accountPtr = getAccountInstanceId(env, thiz); - - LOGD("## oneTimeKeysJni(): IN"); - - if (!accountPtr) - { - LOGE("## oneTimeKeysJni(): failure - invalid Account ptr"); - errorMessage = "invalid Account ptr"; - } - else - { - // keys memory allocation - size_t keysLength = olm_account_one_time_keys_length(accountPtr); - uint8_t *keysBytesPtr = (uint8_t *)malloc(keysLength*sizeof(uint8_t)); - - if (!keysBytesPtr) - { - LOGE("## oneTimeKeysJni(): failure - one time keys array OOM"); - errorMessage = "one time keys array OOM"; - } - else - { - // retrieve key pairs in keysBytesPtr - size_t keysResult = olm_account_one_time_keys(accountPtr, keysBytesPtr, keysLength); - - if (keysResult == olm_error()) { - LOGE("## oneTimeKeysJni(): failure - error getting one time keys 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("## oneTimeKeysJni(): failure - return byte array OOM"); - errorMessage = "return byte array OOM"; - } - else - { - env->SetByteArrayRegion(byteArrayRetValue, 0/*offset*/, keysLength, (const jbyte*)keysBytesPtr); - LOGD("## oneTimeKeysJni(): success"); - } - } - - free(keysBytesPtr); - } - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return byteArrayRetValue; -} - -/** - * Remove the "one time keys" that the session used from the account. - * An exception is thrown if the operation fails. - * @param aNativeOlmSessionId session instance - **/ -JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(removeOneTimeKeysJni)(JNIEnv *env, jobject thiz, jlong aNativeOlmSessionId) -{ - const char* errorMessage = NULL; - OlmAccount* accountPtr = NULL; - OlmSession* sessionPtr = (OlmSession*)aNativeOlmSessionId; - - if (!sessionPtr) - { - LOGE("## removeOneTimeKeysJni(): failure - invalid session ptr"); - errorMessage = "invalid session ptr"; - } - else if (!(accountPtr = getAccountInstanceId(env, thiz))) - { - LOGE("## removeOneTimeKeysJni(): failure - invalid account ptr"); - errorMessage = "invalid account ptr"; - } - else - { - size_t result = olm_remove_one_time_keys(accountPtr, sessionPtr); - - if (result == olm_error()) - { // the account doesn't have any matching "one time keys".. - LOGW("## removeOneTimeKeysJni(): failure - removing one time keys Msg=%s", olm_account_last_error(accountPtr)); - errorMessage = (const char *)olm_account_last_error(accountPtr); - } - else - { - LOGD("## removeOneTimeKeysJni(): success"); - } - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } -} - -/** - * Mark the current set of "one time keys" as being published. - * An exception is thrown if the operation fails. - **/ -JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(markOneTimeKeysAsPublishedJni)(JNIEnv *env, jobject thiz) -{ - const char* errorMessage = NULL; - OlmAccount* accountPtr = getAccountInstanceId(env, thiz); - - if (!accountPtr) - { - LOGE("## markOneTimeKeysAsPublishedJni(): failure - invalid account ptr"); - errorMessage = "invalid account ptr"; - } - else - { - size_t result = olm_account_mark_keys_as_published(accountPtr); - - if (result == olm_error()) - { - LOGW("## markOneTimeKeysAsPublishedJni(): failure - Msg=%s",(const char *)olm_account_last_error(accountPtr)); - errorMessage = (const char *)olm_account_last_error(accountPtr); - } - else - { - LOGD("## markOneTimeKeysAsPublishedJni(): success - retCode=%lu",static_cast<long unsigned int>(result)); - } - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } -} - -/** - * Sign a message with the ed25519 key (fingerprint) for this account.<br> - * The signed message is returned by the function. - * @param aMessage message to sign - * @return the signed message, null otherwise - **/ -JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(signMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aMessage) -{ - const char* errorMessage = NULL; - OlmAccount* accountPtr = NULL; - jbyteArray signedMsgRetValueBuffer = NULL; - - if (!aMessage) - { - LOGE("## signMessageJni(): failure - invalid aMessage param"); - errorMessage = "invalid aMessage param"; - } - else if (!(accountPtr = getAccountInstanceId(env, thiz))) - { - LOGE("## signMessageJni(): failure - invalid account ptr"); - errorMessage = "invalid account ptr"; - } - else - { - int messageLength = env->GetArrayLength(aMessage); - jbyte* messageToSign = env->GetByteArrayElements(aMessage, NULL); - - // signature memory allocation - size_t signatureLength = olm_account_signature_length(accountPtr); - void* signedMsgPtr = malloc(signatureLength * sizeof(uint8_t)); - - if (!signedMsgPtr) - { - LOGE("## signMessageJni(): failure - signature allocation OOM"); - errorMessage = "signature allocation OOM"; - } - else - { - // sign message - size_t resultSign = olm_account_sign(accountPtr, - (void*)messageToSign, - (size_t)messageLength, - signedMsgPtr, - signatureLength); - - if (resultSign == olm_error()) - { - LOGE("## signMessageJni(): failure - error signing message Msg=%s",(const char *)olm_account_last_error(accountPtr)); - errorMessage = (const char *)olm_account_last_error(accountPtr); - } - else - { - LOGD("## signMessageJni(): success - retCode=%lu signatureLength=%lu", static_cast<long unsigned int>(resultSign), static_cast<long unsigned int>(signatureLength)); - - signedMsgRetValueBuffer = env->NewByteArray(signatureLength); - env->SetByteArrayRegion(signedMsgRetValueBuffer, 0 , signatureLength, (jbyte*)signedMsgPtr); - } - - free(signedMsgPtr); - } - - // release messageToSign - if (messageToSign) - { - env->ReleaseByteArrayElements(aMessage, messageToSign, JNI_ABORT); - } - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return signedMsgRetValueBuffer; -} - -/** - * Serialize and encrypt account instance.<br> - * @param aKeyBuffer key used to encrypt the serialized account data - * @return the serialised account as bytes buffer. - **/ -JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKeyBuffer) -{ - const char* errorMessage = NULL; - jbyteArray pickledDataRetValue = 0; - jbyte* keyPtr = NULL; - jboolean keyIsCopied = JNI_FALSE; - OlmAccount* accountPtr = NULL; - - LOGD("## serializeJni(): IN"); - - if (!aKeyBuffer) - { - LOGE(" ## serializeJni(): failure - invalid key"); - errorMessage = "invalid key"; - } - else if (!(accountPtr = getAccountInstanceId(env, thiz))) - { - LOGE(" ## serializeJni(): failure - invalid account ptr"); - errorMessage = "invalid account ptr"; - } - else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, &keyIsCopied))) - { - LOGE(" ## serializeJni(): failure - keyPtr JNI allocation OOM"); - errorMessage = "keyPtr JNI allocation OOM"; - } - else - { - size_t pickledLength = olm_pickle_account_length(accountPtr); - size_t keyLength = (size_t)env->GetArrayLength(aKeyBuffer); - LOGD(" ## serializeJni(): pickledLength=%lu keyLength=%lu",static_cast<long unsigned int>(pickledLength), static_cast<long unsigned int>(keyLength)); - - void* pickledPtr = malloc(pickledLength * sizeof(uint8_t)); - - if (!pickledPtr) - { - LOGE(" ## serializeJni(): failure - pickledPtr buffer OOM"); - errorMessage = "pickledPtr buffer OOM"; - } - else - { - size_t result = olm_pickle_account(accountPtr, - (void const *)keyPtr, - keyLength, - (void*)pickledPtr, - pickledLength); - if (result == olm_error()) - { - errorMessage = olm_account_last_error(accountPtr); - LOGE(" ## serializeJni(): failure - olm_pickle_account() Msg=%s", errorMessage); - } - else - { - LOGD(" ## serializeJni(): success - result=%lu pickled=%.*s", static_cast<long unsigned int>(result), static_cast<int>(pickledLength), static_cast<char*>(pickledPtr)); - pickledDataRetValue = env->NewByteArray(pickledLength); - env->SetByteArrayRegion(pickledDataRetValue, 0 , pickledLength, (jbyte*)pickledPtr); - } - - free(pickledPtr); - } - } - - // free alloc - if (keyPtr) - { - if (keyIsCopied) { - memset(keyPtr, 0, (size_t)env->GetArrayLength(aKeyBuffer)); - } - env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return pickledDataRetValue; -} - -/** - * Allocate a new account and initialise it with the serialisation data.<br> - * @param aSerializedDataBuffer the account serialisation buffer - * @param aKeyBuffer the key used to encrypt the serialized account data - * @return the deserialised account - **/ -JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(deserializeJni)(JNIEnv *env, jobject thiz, jbyteArray aSerializedDataBuffer, jbyteArray aKeyBuffer) -{ - const char* errorMessage = NULL; - - OlmAccount* accountPtr = NULL; - - jbyte* keyPtr = NULL; - jboolean keyIsCopied = JNI_FALSE; - jbyte* pickledPtr = NULL; - - LOGD("## deserializeJni(): IN"); - - if (!aKeyBuffer) - { - LOGE(" ## deserializeJni(): failure - invalid key"); - errorMessage = "invalid key"; - } - else if (!aSerializedDataBuffer) - { - LOGE(" ## deserializeJni(): failure - invalid serialized data"); - errorMessage = "invalid serialized data"; - } - else if (!(accountPtr = initializeAccountMemory())) - { - LOGE(" ## deserializeJni(): failure - account failure OOM"); - errorMessage = "account failure OOM"; - } - else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, &keyIsCopied))) - { - LOGE(" ## deserializeJni(): failure - keyPtr JNI allocation OOM"); - errorMessage = "keyPtr JNI allocation OOM"; - } - else if (!(pickledPtr = env->GetByteArrayElements(aSerializedDataBuffer, 0))) - { - LOGE(" ## deserializeJni(): failure - pickledPtr JNI allocation OOM"); - errorMessage = "pickledPtr JNI allocation OOM"; - } - else - { - size_t pickledLength = (size_t)env->GetArrayLength(aSerializedDataBuffer); - size_t keyLength = (size_t)env->GetArrayLength(aKeyBuffer); - LOGD(" ## deserializeJni(): pickledLength=%lu keyLength=%lu",static_cast<long unsigned int>(pickledLength), static_cast<long unsigned int>(keyLength)); - LOGD(" ## deserializeJni(): pickled=%.*s", static_cast<int> (pickledLength), (char const *)pickledPtr); - - size_t result = olm_unpickle_account(accountPtr, - (void const *)keyPtr, - keyLength, - (void*)pickledPtr, - pickledLength); - if (result == olm_error()) - { - errorMessage = olm_account_last_error(accountPtr); - LOGE(" ## deserializeJni(): failure - olm_unpickle_account() Msg=%s", errorMessage); - } - else - { - LOGD(" ## deserializeJni(): success - result=%lu ", static_cast<long unsigned int>(result)); - } - } - - // free alloc - if (keyPtr) - { - if (keyIsCopied) { - memset(keyPtr, 0, (size_t)env->GetArrayLength(aKeyBuffer)); - } - env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT); - } - - if (pickledPtr) - { - env->ReleaseByteArrayElements(aSerializedDataBuffer, pickledPtr, JNI_ABORT); - } - - if (errorMessage) - { - if (accountPtr) - { - olm_clear_account(accountPtr); - free(accountPtr); - } - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return (jlong)(intptr_t)accountPtr; -} diff --git a/android/olm-sdk/src/main/jni/olm_account.h b/android/olm-sdk/src/main/jni/olm_account.h deleted file mode 100644 index eda434d..0000000 --- a/android/olm-sdk/src/main/jni/olm_account.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2017 OpenMarket Ltd - * Copyright 2017 Vector Creations 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 _OLMACCOUNT_H -#define _OLMACCOUNT_H - -#include "olm_jni.h" -#include "olm/olm.h" - -#define OLM_ACCOUNT_FUNC_DEF(func_name) FUNC_DEF(OlmAccount,func_name) -#define OLM_MANAGER_FUNC_DEF(func_name) FUNC_DEF(OlmManager,func_name) - -#ifdef __cplusplus -extern "C" { -#endif - -// account creation/destruction -JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(releaseAccountJni)(JNIEnv *env, jobject thiz); -JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(createNewAccountJni)(JNIEnv *env, jobject thiz); - -// identity keys -JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(identityKeysJni)(JNIEnv *env, jobject thiz); - -// one time keys -JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(oneTimeKeysJni)(JNIEnv *env, jobject thiz); -JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(maxOneTimeKeysJni)(JNIEnv *env, jobject thiz); -JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(generateOneTimeKeysJni)(JNIEnv *env, jobject thiz, jint aNumberOfKeys); -JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(removeOneTimeKeysJni)(JNIEnv *env, jobject thiz, jlong aNativeOlmSessionId); -JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(markOneTimeKeysAsPublishedJni)(JNIEnv *env, jobject thiz); - -// signing -JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(signMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aMessage); - -// serialization -JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKeyBuffer); -JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(deserializeJni)(JNIEnv *env, jobject thiz, jbyteArray aSerializedDataBuffer, jbyteArray aKeyBuffer); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/android/olm-sdk/src/main/jni/olm_inbound_group_session.cpp b/android/olm-sdk/src/main/jni/olm_inbound_group_session.cpp deleted file mode 100644 index ae9ecf1..0000000 --- a/android/olm-sdk/src/main/jni/olm_inbound_group_session.cpp +++ /dev/null @@ -1,654 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016 Vector Creations 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. - */ - -#include "olm_inbound_group_session.h" - -using namespace AndroidOlmSdk; - -/** - * Release the session allocation made by initializeInboundGroupSessionMemory().<br> - * This method MUST be called when java counter part account instance is done. - */ -JNIEXPORT void OLM_INBOUND_GROUP_SESSION_FUNC_DEF(releaseSessionJni)(JNIEnv *env, jobject thiz) -{ - OlmInboundGroupSession* sessionPtr = getInboundGroupSessionInstanceId(env,thiz); - - LOGD("## releaseSessionJni(): InBound group session IN"); - - if (!sessionPtr) - { - LOGE("## releaseSessionJni(): failure - invalid inbound group session instance"); - } - else - { - LOGD(" ## releaseSessionJni(): sessionPtr=%p", sessionPtr); -#ifdef ENABLE_JNI_LOG - size_t retCode = olm_clear_inbound_group_session(sessionPtr); - LOGD(" ## releaseSessionJni(): clear_inbound_group_session=%lu",static_cast<long unsigned int>(retCode)); -#else - olm_clear_inbound_group_session(sessionPtr); -#endif - - LOGD(" ## releaseSessionJni(): free IN"); - free(sessionPtr); - LOGD(" ## releaseSessionJni(): free OUT"); - } -} - -/** - * Initialize a new inbound group session and return it to JAVA side.<br> - * Since a C prt is returned as a jlong, special care will be taken - * to make the cast (OlmInboundGroupSession* => jlong) platform independent. - * @param aSessionKeyBuffer session key from an outbound session - * @param isImported true when the session key has been retrieved from a backup - * @return the initialized OlmInboundGroupSession* instance or throw an exception it fails. - **/ -JNIEXPORT jlong OLM_INBOUND_GROUP_SESSION_FUNC_DEF(createNewSessionJni)(JNIEnv *env, jobject thiz, jbyteArray aSessionKeyBuffer, jboolean isImported) -{ - const char* errorMessage = NULL; - OlmInboundGroupSession* sessionPtr = NULL; - jbyte* sessionKeyPtr = NULL; - jboolean sessionWasCopied = JNI_FALSE; - size_t sessionSize = olm_inbound_group_session_size(); - - LOGD("## createNewSessionJni(): inbound group session IN"); - - if (!sessionSize) - { - LOGE(" ## createNewSessionJni(): failure - inbound group session size = 0"); - errorMessage = "inbound group session size = 0"; - } - else if (!(sessionPtr = (OlmInboundGroupSession*)malloc(sessionSize))) - { - LOGE(" ## createNewSessionJni(): failure - inbound group session OOM"); - errorMessage = "inbound group session OOM"; - } - else if (!aSessionKeyBuffer) - { - LOGE(" ## createNewSessionJni(): failure - invalid aSessionKey"); - errorMessage = "invalid aSessionKey"; - } - else if (!(sessionKeyPtr = env->GetByteArrayElements(aSessionKeyBuffer, &sessionWasCopied))) - { - LOGE(" ## createNewSessionJni(): failure - session key JNI allocation OOM"); - errorMessage = "Session key JNI allocation OOM"; - } - else - { - sessionPtr = olm_inbound_group_session(sessionPtr); - - size_t sessionKeyLength = (size_t)env->GetArrayLength(aSessionKeyBuffer); - LOGD(" ## createNewSessionJni(): sessionKeyLength=%lu", static_cast<long unsigned int>(sessionKeyLength)); - - size_t sessionResult; - - if (JNI_FALSE == isImported) - { - LOGD(" ## createNewSessionJni(): init"); - sessionResult = olm_init_inbound_group_session(sessionPtr, (const uint8_t*)sessionKeyPtr, sessionKeyLength); - } - else - { - LOGD(" ## createNewSessionJni(): import"); - sessionResult = olm_import_inbound_group_session(sessionPtr, (const uint8_t*)sessionKeyPtr, sessionKeyLength); - } - - if (sessionResult == olm_error()) - { - errorMessage = olm_inbound_group_session_last_error(sessionPtr); - LOGE(" ## createNewSessionJni(): failure - init inbound session creation Msg=%s", errorMessage); - } - else - { - LOGD(" ## createNewSessionJni(): success - result=%lu", static_cast<long unsigned int>(sessionResult)); - } - } - - if (sessionKeyPtr) - { - if (sessionWasCopied) { - memset(sessionKeyPtr, 0, (size_t)env->GetArrayLength(aSessionKeyBuffer)); - } - env->ReleaseByteArrayElements(aSessionKeyBuffer, sessionKeyPtr, JNI_ABORT); - } - - if (errorMessage) - { - // release the allocated session - if (sessionPtr) - { - olm_clear_inbound_group_session(sessionPtr); - free(sessionPtr); - } - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return (jlong)(intptr_t)sessionPtr; -} - -/** - * Get a base64-encoded identifier for this inbound group session. - * An exception is thrown if the operation fails. - * @return the base64-encoded identifier - */ -JNIEXPORT jbyteArray OLM_INBOUND_GROUP_SESSION_FUNC_DEF(sessionIdentifierJni)(JNIEnv *env, jobject thiz) -{ - const char* errorMessage = NULL; - OlmInboundGroupSession *sessionPtr = getInboundGroupSessionInstanceId(env, thiz); - jbyteArray returnValue = 0; - - LOGD("## sessionIdentifierJni(): inbound group session IN"); - - if (!sessionPtr) - { - LOGE(" ## sessionIdentifierJni(): failure - invalid inbound group session instance"); - errorMessage = "invalid inbound group session instance"; - } - else - { - // get the size to alloc - size_t lengthSessionId = olm_inbound_group_session_id_length(sessionPtr); - LOGD(" ## sessionIdentifierJni(): inbound group session lengthSessionId=%lu",static_cast<long unsigned int>(lengthSessionId)); - - uint8_t *sessionIdPtr = (uint8_t*)malloc(lengthSessionId*sizeof(uint8_t)); - - if (!sessionIdPtr) - { - LOGE(" ## sessionIdentifierJni(): failure - inbound group session identifier allocation OOM"); - errorMessage = "inbound group session identifier allocation OOM"; - } - else - { - size_t result = olm_inbound_group_session_id(sessionPtr, sessionIdPtr, lengthSessionId); - - if (result == olm_error()) - { - errorMessage = (const char *)olm_inbound_group_session_last_error(sessionPtr); - LOGE(" ## sessionIdentifierJni(): failure - get inbound group session identifier failure Msg=%s",(const char *)olm_inbound_group_session_last_error(sessionPtr)); - } - else - { - LOGD(" ## sessionIdentifierJni(): success - inbound group session result=%lu sessionId=%.*s",static_cast<long unsigned int>(result), static_cast<int>(result), (char*)sessionIdPtr); - - returnValue = env->NewByteArray(result); - env->SetByteArrayRegion(returnValue, 0 , result, (jbyte*)sessionIdPtr); - } - - free(sessionIdPtr); - } - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return returnValue; -} - -/** - * Decrypt a message. - * An exception is thrown if the operation fails. - * @param aEncryptedMsg the encrypted message - * @param aDecryptMessageResult the decryptMessage information - * @return the decrypted message - */ -JNIEXPORT jbyteArray OLM_INBOUND_GROUP_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aEncryptedMsgBuffer, jobject aDecryptionResult) -{ - jbyteArray decryptedMsgBuffer = 0; - const char* errorMessage = NULL; - - OlmInboundGroupSession *sessionPtr = getInboundGroupSessionInstanceId(env, thiz); - jbyte *encryptedMsgPtr = NULL; - jclass indexObjJClass = 0; - jfieldID indexMsgFieldId; - - LOGD("## decryptMessageJni(): inbound group session IN"); - - if (!sessionPtr) - { - LOGE(" ## decryptMessageJni(): failure - invalid inbound group session ptr=NULL"); - errorMessage = "invalid inbound group session ptr=NULL"; - } - else if (!aEncryptedMsgBuffer) - { - LOGE(" ## decryptMessageJni(): failure - invalid encrypted message"); - errorMessage = "invalid encrypted message"; - } - else if (!aDecryptionResult) - { - LOGE(" ## decryptMessageJni(): failure - invalid index object"); - errorMessage = "invalid index object"; - } - else if (!(encryptedMsgPtr = env->GetByteArrayElements(aEncryptedMsgBuffer, 0))) - { - LOGE(" ## decryptMessageJni(): failure - encrypted message JNI allocation OOM"); - errorMessage = "encrypted message JNI allocation OOM"; - } - else if (!(indexObjJClass = env->GetObjectClass(aDecryptionResult))) - { - LOGE("## decryptMessageJni(): failure - unable to get index class"); - errorMessage = "unable to get index class"; - } - else if (!(indexMsgFieldId = env->GetFieldID(indexObjJClass,"mIndex","J"))) - { - LOGE("## decryptMessageJni(): failure - unable to get index type field"); - errorMessage = "unable to get index type field"; - } - else - { - // get encrypted message length - size_t encryptedMsgLength = (size_t)env->GetArrayLength(aEncryptedMsgBuffer); - uint8_t *tempEncryptedPtr = static_cast<uint8_t*>(malloc(encryptedMsgLength*sizeof(uint8_t))); - - // create a dedicated temp buffer to be used in next Olm API calls - if (!tempEncryptedPtr) - { - LOGE(" ## decryptMessageJni(): failure - tempEncryptedPtr allocation OOM"); - errorMessage = "tempEncryptedPtr allocation OOM"; - } - else - { - memcpy(tempEncryptedPtr, encryptedMsgPtr, encryptedMsgLength); - LOGD(" ## decryptMessageJni(): encryptedMsgLength=%lu encryptedMsg=%.*s",static_cast<long unsigned int>(encryptedMsgLength), static_cast<int>(encryptedMsgLength), encryptedMsgPtr); - - // get max plaintext length - size_t maxPlainTextLength = olm_group_decrypt_max_plaintext_length(sessionPtr, - tempEncryptedPtr, - encryptedMsgLength); - if (maxPlainTextLength == olm_error()) - { - errorMessage = olm_inbound_group_session_last_error(sessionPtr); - LOGE(" ## decryptMessageJni(): failure - olm_group_decrypt_max_plaintext_length Msg=%s", errorMessage); - } - else - { - LOGD(" ## decryptMessageJni(): maxPlaintextLength=%lu",static_cast<long unsigned int>(maxPlainTextLength)); - - uint32_t messageIndex = 0; - - // allocate output decrypted message - uint8_t *plainTextMsgPtr = static_cast<uint8_t*>(malloc(maxPlainTextLength*sizeof(uint8_t))); - - // decrypt, but before reload encrypted buffer (previous one was destroyed) - memcpy(tempEncryptedPtr, encryptedMsgPtr, encryptedMsgLength); - size_t plaintextLength = olm_group_decrypt(sessionPtr, - tempEncryptedPtr, - encryptedMsgLength, - plainTextMsgPtr, - maxPlainTextLength, - &messageIndex); - if (plaintextLength == olm_error()) - { - errorMessage = olm_inbound_group_session_last_error(sessionPtr); - LOGE(" ## decryptMessageJni(): failure - olm_group_decrypt Msg=%s", errorMessage); - } - else - { - // update index - env->SetLongField(aDecryptionResult, indexMsgFieldId, (jlong)messageIndex); - - decryptedMsgBuffer = env->NewByteArray(plaintextLength); - env->SetByteArrayRegion(decryptedMsgBuffer, 0 , plaintextLength, (jbyte*)plainTextMsgPtr); - - LOGD(" ## decryptMessageJni(): UTF-8 Conversion - decrypted returnedLg=%lu OK",static_cast<long unsigned int>(plaintextLength)); - } - - if (plainTextMsgPtr) - { - memset(plainTextMsgPtr, 0, maxPlainTextLength*sizeof(uint8_t)); - free(plainTextMsgPtr); - } - } - - if (tempEncryptedPtr) - { - free(tempEncryptedPtr); - } - } - } - - // free alloc - if (encryptedMsgPtr) - { - env->ReleaseByteArrayElements(aEncryptedMsgBuffer, encryptedMsgPtr, JNI_ABORT); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return decryptedMsgBuffer; -} - -/** - * Provides the first known index. - * An exception is thrown if the operation fails. - * @return the first known index - */ -JNIEXPORT jlong OLM_INBOUND_GROUP_SESSION_FUNC_DEF(firstKnownIndexJni)(JNIEnv *env, jobject thiz) -{ - const char* errorMessage = NULL; - OlmInboundGroupSession *sessionPtr = getInboundGroupSessionInstanceId(env, thiz); - long returnValue = 0; - - LOGD("## firstKnownIndexJni(): inbound group session IN"); - - if (!sessionPtr) - { - LOGE(" ## firstKnownIndexJni(): failure - invalid inbound group session instance"); - errorMessage = "invalid inbound group session instance"; - } - else - { - returnValue = olm_inbound_group_session_first_known_index(sessionPtr); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return returnValue; -} - -/** - * Tells if the session is verified. - * An exception is thrown if the operation fails. - * @return true if the session is verified - */ -JNIEXPORT jboolean OLM_INBOUND_GROUP_SESSION_FUNC_DEF(isVerifiedJni)(JNIEnv *env, jobject thiz) -{ - const char* errorMessage = NULL; - OlmInboundGroupSession *sessionPtr = getInboundGroupSessionInstanceId(env, thiz); - jboolean returnValue = JNI_FALSE; - - LOGD("## isVerifiedJni(): inbound group session IN"); - - if (!sessionPtr) - { - LOGE(" ## isVerifiedJni(): failure - invalid inbound group session instance"); - errorMessage = "invalid inbound group session instance"; - } - else - { - LOGE(" ## isVerifiedJni(): faaa %d", olm_inbound_group_session_is_verified(sessionPtr)); - - returnValue = (0 != olm_inbound_group_session_is_verified(sessionPtr)) ? JNI_TRUE : JNI_FALSE; - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return returnValue; -} - -/** - * Exports the session as byte array from a message index - * An exception is thrown if the operation fails. - * @param messageIndex key used to encrypt the serialized session data - * @return the session saved as bytes array - **/ -JNIEXPORT jbyteArray OLM_INBOUND_GROUP_SESSION_FUNC_DEF(exportJni)(JNIEnv *env, jobject thiz, jlong messageIndex) { - jbyteArray exportedByteArray = 0; - const char* errorMessage = NULL; - OlmInboundGroupSession *sessionPtr = getInboundGroupSessionInstanceId(env, thiz); - - LOGD("## exportJni(): inbound group session IN"); - - if (!sessionPtr) - { - LOGE(" ## exportJni (): failure - invalid inbound group session instance"); - errorMessage = "invalid inbound group session instance"; - } - else - { - size_t length = olm_export_inbound_group_session_length(sessionPtr); - - LOGD(" ## exportJni(): length =%lu", static_cast<long unsigned int>(length)); - - void *bufferPtr = malloc(length * sizeof(uint8_t)); - - if (!bufferPtr) - { - LOGE(" ## exportJni(): failure - pickledPtr buffer OOM"); - errorMessage = "pickledPtr buffer OOM"; - } - else - { - size_t result = olm_export_inbound_group_session(sessionPtr, - (uint8_t*)bufferPtr, - length, - (long) messageIndex); - - if (result == olm_error()) - { - errorMessage = olm_inbound_group_session_last_error(sessionPtr); - LOGE(" ## exportJni(): failure - olm_export_inbound_group_session() Msg=%s", errorMessage); - } - else - { - LOGD(" ## exportJni(): success - result=%lu buffer=%.*s", static_cast<long unsigned int>(result), static_cast<int>(length), static_cast<char*>(bufferPtr)); - - exportedByteArray = env->NewByteArray(length); - env->SetByteArrayRegion(exportedByteArray, 0 , length, (jbyte*)bufferPtr); - - // clean before leaving - memset(bufferPtr, 0, length); - } - - free(bufferPtr); - } - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return exportedByteArray; -} - -/** - * Serialize and encrypt session instance into a base64 string.<br> - * An exception is thrown if the operation fails. - * @param aKeyBuffer key used to encrypt the serialized session data - * @return a base64 string if operation succeed, null otherwise - **/ -JNIEXPORT jbyteArray OLM_INBOUND_GROUP_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKeyBuffer) -{ - const char* errorMessage = NULL; - - jbyteArray pickledDataRet = 0; - jbyte* keyPtr = NULL; - jboolean keyWasCopied = JNI_FALSE; - OlmInboundGroupSession* sessionPtr = getInboundGroupSessionInstanceId(env, thiz); - - LOGD("## inbound group session serializeJni(): IN"); - - if (!sessionPtr) - { - LOGE(" ## serializeJni(): failure - invalid session ptr"); - errorMessage = "invalid session ptr"; - } - else if (!aKeyBuffer) - { - LOGE(" ## serializeJni(): failure - invalid key"); - errorMessage = "invalid key"; - } - else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, &keyWasCopied))) - { - LOGE(" ## serializeJni(): failure - keyPtr JNI allocation OOM"); - errorMessage = "keyPtr JNI allocation OOM"; - } - else - { - size_t pickledLength = olm_pickle_inbound_group_session_length(sessionPtr); - size_t keyLength = (size_t)env->GetArrayLength(aKeyBuffer); - LOGD(" ## serializeJni(): pickledLength=%lu keyLength=%lu", static_cast<long unsigned int>(pickledLength), static_cast<long unsigned int>(keyLength)); - - void *pickledPtr = malloc(pickledLength*sizeof(uint8_t)); - - if (!pickledPtr) - { - LOGE(" ## serializeJni(): failure - pickledPtr buffer OOM"); - errorMessage = "pickledPtr buffer OOM"; - } - else - { - size_t result = olm_pickle_inbound_group_session(sessionPtr, - (void const *)keyPtr, - keyLength, - (void*)pickledPtr, - pickledLength); - if (result == olm_error()) - { - errorMessage = olm_inbound_group_session_last_error(sessionPtr); - LOGE(" ## serializeJni(): failure - olm_pickle_outbound_group_session() Msg=%s", errorMessage); - } - else - { - LOGD(" ## serializeJni(): success - result=%lu pickled=%.*s", static_cast<long unsigned int>(result), static_cast<int>(pickledLength), static_cast<char*>(pickledPtr)); - - pickledDataRet = env->NewByteArray(pickledLength); - env->SetByteArrayRegion(pickledDataRet, 0 , pickledLength, (jbyte*)pickledPtr); - } - - free(pickledPtr); - } - } - - // free alloc - if (keyPtr) - { - if (keyWasCopied) { - memset(keyPtr, 0, (size_t)env->GetArrayLength(aKeyBuffer)); - } - env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return pickledDataRet; -} - -/** - * Allocate a new session and initialize it with the serialisation data.<br> - * An exception is thrown if the operation fails. - * @param aSerializedData the session serialisation buffer - * @param aKey the key used to encrypt the serialized account data - * @return the deserialized session - **/ -JNIEXPORT jlong OLM_INBOUND_GROUP_SESSION_FUNC_DEF(deserializeJni)(JNIEnv *env, jobject thiz, jbyteArray aSerializedDataBuffer, jbyteArray aKeyBuffer) -{ - const char* errorMessage = NULL; - - OlmInboundGroupSession* sessionPtr = NULL; - size_t sessionSize = olm_inbound_group_session_size(); - jbyte* keyPtr = NULL; - jboolean keyWasCopied = JNI_FALSE; - jbyte* pickledPtr = NULL; - - LOGD("## deserializeJni(): IN"); - - if (!sessionSize) - { - LOGE(" ## deserializeJni(): failure - inbound group session size = 0"); - errorMessage = "inbound group session size = 0"; - } - else if (!(sessionPtr = (OlmInboundGroupSession*)malloc(sessionSize))) - { - LOGE(" ## deserializeJni(): failure - session failure OOM"); - errorMessage = "session failure OOM"; - } - else if (!aKeyBuffer) - { - LOGE(" ## deserializeJni(): failure - invalid key"); - errorMessage = "invalid key"; - } - else if (!aSerializedDataBuffer) - { - LOGE(" ## deserializeJni(): failure - serialized data"); - errorMessage = "serialized data"; - } - else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, &keyWasCopied))) - { - LOGE(" ## deserializeJni(): failure - keyPtr JNI allocation OOM"); - errorMessage = "keyPtr JNI allocation OOM"; - } - else if (!(pickledPtr = env->GetByteArrayElements(aSerializedDataBuffer, 0))) - { - LOGE(" ## deserializeJni(): failure - pickledPtr JNI allocation OOM"); - errorMessage = "pickledPtr JNI allocation OOM"; - } - else - { - sessionPtr = olm_inbound_group_session(sessionPtr); - - size_t pickledLength = (size_t)env->GetArrayLength(aSerializedDataBuffer); - size_t keyLength = (size_t)env->GetArrayLength(aKeyBuffer); - LOGD(" ## deserializeJni(): pickledLength=%lu keyLength=%lu",static_cast<long unsigned int>(pickledLength), static_cast<long unsigned int>(keyLength)); - LOGD(" ## deserializeJni(): pickled=%.*s", static_cast<int>(pickledLength), (char const *)pickledPtr); - - size_t result = olm_unpickle_inbound_group_session(sessionPtr, - (void const *)keyPtr, - keyLength, - (void*)pickledPtr, - pickledLength); - if (result == olm_error()) - { - errorMessage = olm_inbound_group_session_last_error(sessionPtr); - LOGE(" ## deserializeJni(): failure - olm_unpickle_inbound_group_session() Msg=%s", errorMessage); - } - else - { - LOGD(" ## deserializeJni(): success - result=%lu ", static_cast<long unsigned int>(result)); - } - } - - // free alloc - if (keyPtr) - { - if (keyWasCopied) { - memset(keyPtr, 0, (size_t)env->GetArrayLength(aKeyBuffer)); - } - env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT); - } - - if (pickledPtr) - { - env->ReleaseByteArrayElements(aSerializedDataBuffer, pickledPtr, JNI_ABORT); - } - - if (errorMessage) - { - if (sessionPtr) - { - olm_clear_inbound_group_session(sessionPtr); - free(sessionPtr); - } - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return (jlong)(intptr_t)sessionPtr; -} diff --git a/android/olm-sdk/src/main/jni/olm_inbound_group_session.h b/android/olm-sdk/src/main/jni/olm_inbound_group_session.h deleted file mode 100644 index b4d21eb..0000000 --- a/android/olm-sdk/src/main/jni/olm_inbound_group_session.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016 Vector Creations 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 _OLMINBOUND_GROUP_SESSION_H -#define _OLMINBOUND_GROUP_SESSION_H - -#include "olm_jni.h" -#include "olm/olm.h" -#include "olm/inbound_group_session.h" - -#define OLM_INBOUND_GROUP_SESSION_FUNC_DEF(func_name) FUNC_DEF(OlmInboundGroupSession,func_name) - -#ifdef __cplusplus -extern "C" { -#endif - -// session creation/destruction -JNIEXPORT void OLM_INBOUND_GROUP_SESSION_FUNC_DEF(releaseSessionJni)(JNIEnv *env, jobject thiz); -JNIEXPORT jlong OLM_INBOUND_GROUP_SESSION_FUNC_DEF(createNewSessionJni)(JNIEnv *env, jobject thiz, jbyteArray aSessionKeyBuffer, jboolean isImported); - -JNIEXPORT jbyteArray OLM_INBOUND_GROUP_SESSION_FUNC_DEF(sessionIdentifierJni)(JNIEnv *env, jobject thiz); -JNIEXPORT jbyteArray OLM_INBOUND_GROUP_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aEncryptedMsg, jobject aDecryptIndex); - -JNIEXPORT jlong OLM_INBOUND_GROUP_SESSION_FUNC_DEF(firstKnownIndexJni)(JNIEnv *env, jobject thiz); -JNIEXPORT jboolean OLM_INBOUND_GROUP_SESSION_FUNC_DEF(isVerifiedJni)(JNIEnv *env, jobject thiz); - -JNIEXPORT jbyteArray OLM_INBOUND_GROUP_SESSION_FUNC_DEF(exportJni)(JNIEnv *env, jobject thiz, jlong messageIndex); - -// serialization -JNIEXPORT jbyteArray OLM_INBOUND_GROUP_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKey); -JNIEXPORT jlong OLM_INBOUND_GROUP_SESSION_FUNC_DEF(deserializeJni)(JNIEnv *env, jobject thiz, jbyteArray aSerializedData, jbyteArray aKey); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/android/olm-sdk/src/main/jni/olm_jni.h b/android/olm-sdk/src/main/jni/olm_jni.h deleted file mode 100644 index 110f089..0000000 --- a/android/olm-sdk/src/main/jni/olm_jni.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016,2018,2019 Vector Creations 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 _OLMJNI_H -#define _OLMJNI_H - -#include <cstdlib> -#include <cstdio> -#include <string> -#include <string.h> -#include <sstream> -#include <jni.h> -#include <android/log.h> - - -#define TAG "OlmJniNative" - -/* logging macros */ -//#define ENABLE_JNI_LOG - -#ifdef NDK_DEBUG - #warning NDK_DEBUG is defined! -#endif - -#ifdef ENABLE_JNI_LOG - #warning ENABLE_JNI_LOG is defined! -#endif - -#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__) - -#ifdef ENABLE_JNI_LOG - #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__) - #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__) -#else - #define LOGD(...) - #define LOGW(...) -#endif - -#define FUNC_DEF(class_name,func_name) JNICALL Java_org_matrix_olm_##class_name##_##func_name - -namespace AndroidOlmSdk -{ - -} - - -#ifdef __cplusplus -extern "C" { -#endif - -// internal helper functions -bool setRandomInBuffer(JNIEnv *env, uint8_t **aBuffer2Ptr, size_t aRandomSize); - -struct OlmSession* getSessionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject); -struct OlmAccount* getAccountInstanceId(JNIEnv* aJniEnv, jobject aJavaObject); -struct OlmInboundGroupSession* getInboundGroupSessionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject); -struct OlmOutboundGroupSession* getOutboundGroupSessionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject); -struct OlmUtility* getUtilityInstanceId(JNIEnv* aJniEnv, jobject aJavaObject); -struct OlmPkDecryption* getPkDecryptionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject); -struct OlmPkEncryption* getPkEncryptionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject); -struct OlmPkSigning* getPkSigningInstanceId(JNIEnv* aJniEnv, jobject aJavaObject); -struct OlmSAS* getOlmSasInstanceId(JNIEnv* aJniEnv, jobject aJavaObject); - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/android/olm-sdk/src/main/jni/olm_jni_helper.cpp b/android/olm-sdk/src/main/jni/olm_jni_helper.cpp deleted file mode 100644 index 47f83a8..0000000 --- a/android/olm-sdk/src/main/jni/olm_jni_helper.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016,2018,2019 Vector Creations 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. - */ - -#include "olm_jni_helper.h" -#include "olm/olm.h" -#include <sys/time.h> - -using namespace AndroidOlmSdk; - -/** -* Init a buffer with a given number of random values. -* @param aBuffer2Ptr the buffer to be initialized -* @param aRandomSize the number of random values to apply -* @return true if operation succeed, false otherwise -**/ -bool setRandomInBuffer(JNIEnv *env, uint8_t **aBuffer2Ptr, size_t aRandomSize) -{ - bool retCode = false; - int bufferLen = aRandomSize*sizeof(uint8_t); - - if (!aBuffer2Ptr) - { - LOGE("## setRandomInBuffer(): failure - aBuffer=NULL"); - } - else if (!aRandomSize) - { - LOGE("## setRandomInBuffer(): failure - random size=0"); - } - else if (!(*aBuffer2Ptr = (uint8_t*)malloc(bufferLen))) - { - LOGE("## setRandomInBuffer(): failure - alloc mem OOM"); - } - else - { - LOGD("## setRandomInBuffer(): randomSize=%lu",static_cast<long unsigned int>(aRandomSize)); - - // use the secureRandom class - jclass cls = env->FindClass("java/security/SecureRandom"); - - if (cls) - { - jobject newObj = 0; - jmethodID constructor = env->GetMethodID(cls, "<init>", "()V"); - jmethodID nextByteMethod = env->GetMethodID(cls, "nextBytes", "([B)V"); - - if (constructor) - { - newObj = env->NewObject(cls, constructor); - jbyteArray tempByteArray = env->NewByteArray(bufferLen); - - if (newObj && tempByteArray) - { - env->CallVoidMethod(newObj, nextByteMethod, tempByteArray); - - if (!env->ExceptionOccurred()) - { - jbyte* buffer = env->GetByteArrayElements(tempByteArray, NULL); - - if (buffer) - { - memcpy(*aBuffer2Ptr, buffer, bufferLen); - retCode = true; - - // clear tempByteArray to hide sensitive data. - memset(buffer, 0, bufferLen); - env->SetByteArrayRegion(tempByteArray, 0, bufferLen, buffer); - - // ensure that the buffer is released - env->ReleaseByteArrayElements(tempByteArray, buffer, JNI_ABORT); - } - } - } - - if (tempByteArray) - { - env->DeleteLocalRef(tempByteArray); - } - - if (newObj) - { - env->DeleteLocalRef(newObj); - } - } - } - - // debug purpose - /*for(int i = 0; i < aRandomSize; i++) - { - LOGD("## setRandomInBuffer(): randomBuffPtr[%ld]=%d",i, (*aBuffer2Ptr)[i]); - }*/ - } - - return retCode; -} - -/** -* Read the instance ID of the calling object. -* @param aJniEnv pointer pointing on the JNI function table -* @param aJavaObject reference to the object on which the method is invoked -* @param aCallingClass java calling class name -* @return the related instance ID -**/ -jlong getInstanceId(JNIEnv* aJniEnv, jobject aJavaObject, const char *aCallingClass) -{ - jlong instanceId = 0; - - if (aJniEnv) - { - jclass requiredClass = aJniEnv->FindClass(aCallingClass); - jclass loaderClass = 0; - - if (requiredClass && (JNI_TRUE != aJniEnv->IsInstanceOf(aJavaObject, requiredClass))) - { - LOGE("## getInstanceId() failure - invalid instance of"); - } - else if ((loaderClass = aJniEnv->GetObjectClass(aJavaObject))) - { - jfieldID instanceIdField = aJniEnv->GetFieldID(loaderClass, "mNativeId", "J"); - - if (instanceIdField) - { - instanceId = aJniEnv->GetLongField(aJavaObject, instanceIdField); - LOGD("## getInstanceId(): read from java instanceId=%lld",instanceId); - } - else - { - LOGE("## getInstanceId() ERROR! GetFieldID=null"); - } - - aJniEnv->DeleteLocalRef(loaderClass); - } - else - { - LOGE("## getInstanceId() ERROR! GetObjectClass=null"); - } - } - else - { - LOGE("## getInstanceId() ERROR! aJniEnv=NULL"); - } - - LOGD("## getInstanceId() success - instanceId=%p (jlong)(intptr_t)instanceId=%lld",(void*)instanceId, (jlong)(intptr_t)instanceId); - - return instanceId; -} - -/** -* Read the account instance ID of the calling object. -* @param aJniEnv pointer pointing on the JNI function table -* @param aJavaObject reference to the object on which the method is invoked -* @return the related OlmAccount. -**/ -struct OlmAccount* getAccountInstanceId(JNIEnv* aJniEnv, jobject aJavaObject) -{ - return (struct OlmAccount*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_ACCOUNT); -} - -/** -* Read the session instance ID of the calling object (aJavaObject).<br> -* @param aJniEnv pointer pointing on the JNI function table -* @param aJavaObject reference to the object on which the method is invoked -* @return the related OlmSession. -**/ -struct OlmSession* getSessionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject) -{ - return (struct OlmSession*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_SESSION); -} - -/** -* Read the inbound group session instance ID of the calling object (aJavaObject).<br> -* @param aJniEnv pointer pointing on the JNI function table -* @param aJavaObject reference to the object on which the method is invoked -* @return the related OlmInboundGroupSession. -**/ -struct OlmInboundGroupSession* getInboundGroupSessionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject) -{ - return (struct OlmInboundGroupSession*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_INBOUND_GROUP_SESSION); -} - -/** -* Read the outbound group session instance ID of the calling object (aJavaObject).<br> -* @param aJniEnv pointer pointing on the JNI function table -* @param aJavaObject reference to the object on which the method is invoked -* @return the related OlmOutboundGroupSession -**/ -struct OlmOutboundGroupSession* getOutboundGroupSessionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject) -{ - return (struct OlmOutboundGroupSession*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_OUTBOUND_GROUP_SESSION); -} - -/** -* Read the utility instance ID of the calling object (aJavaObject).<br> -* @param aJniEnv pointer pointing on the JNI function table -* @param aJavaObject reference to the object on which the method is invoked -* @return the related OlmUtility -**/ -struct OlmUtility* getUtilityInstanceId(JNIEnv* aJniEnv, jobject aJavaObject) -{ - return (struct OlmUtility*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_UTILITY); -} - -struct OlmPkDecryption* getPkDecryptionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject) -{ - return (struct OlmPkDecryption*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_PK_DECRYPTION); -} - -struct OlmPkEncryption* getPkEncryptionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject) -{ - return (struct OlmPkEncryption*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_PK_ENCRYPTION); -} - -struct OlmPkSigning* getPkSigningInstanceId(JNIEnv* aJniEnv, jobject aJavaObject) -{ - return (struct OlmPkSigning*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_PK_SIGNING); -} - -struct OlmSAS* getOlmSasInstanceId(JNIEnv* aJniEnv, jobject aJavaObject) -{ - return (struct OlmSAS*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_SAS); -} diff --git a/android/olm-sdk/src/main/jni/olm_jni_helper.h b/android/olm-sdk/src/main/jni/olm_jni_helper.h deleted file mode 100644 index 22552b4..0000000 --- a/android/olm-sdk/src/main/jni/olm_jni_helper.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016,2018,2019 Vector Creations 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. - */ - -#include "olm_jni.h" - -// constant strings -namespace AndroidOlmSdk -{ - static const char *CLASS_OLM_INBOUND_GROUP_SESSION = "org/matrix/olm/OlmInboundGroupSession"; - static const char *CLASS_OLM_OUTBOUND_GROUP_SESSION = "org/matrix/olm/OlmOutboundGroupSession"; - static const char *CLASS_OLM_SESSION = "org/matrix/olm/OlmSession"; - static const char *CLASS_OLM_ACCOUNT = "org/matrix/olm/OlmAccount"; - static const char *CLASS_OLM_UTILITY = "org/matrix/olm/OlmUtility"; - static const char *CLASS_OLM_PK_ENCRYPTION = "org/matrix/olm/OlmPkEncryption"; - static const char *CLASS_OLM_PK_DECRYPTION = "org/matrix/olm/OlmPkDecryption"; - static const char *CLASS_OLM_PK_SIGNING = "org/matrix/olm/OlmPkSigning"; - static const char *CLASS_OLM_SAS = "org/matrix/olm/OlmSAS"; -} diff --git a/android/olm-sdk/src/main/jni/olm_manager.cpp b/android/olm-sdk/src/main/jni/olm_manager.cpp deleted file mode 100644 index 8ee0df7..0000000 --- a/android/olm-sdk/src/main/jni/olm_manager.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016 Vector Creations 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. - */ - -#include "olm_manager.h" - -using namespace AndroidOlmSdk; - -JNIEXPORT jstring OLM_MANAGER_FUNC_DEF(getOlmLibVersionJni)(JNIEnv* env, jobject thiz) -{ - uint8_t majorVer=0, minorVer=0, patchVer=0; - jstring returnValueStr=0; - char buff[150]; - - olm_get_library_version(&majorVer, &minorVer, &patchVer); - LOGD("## getOlmLibVersionJni(): Major=%d Minor=%d Patch=%d", majorVer, minorVer, patchVer); - - snprintf(buff, sizeof(buff), "%d.%d.%d", majorVer, minorVer, patchVer); - returnValueStr = env->NewStringUTF((const char*)buff); - - return returnValueStr; -}
\ No newline at end of file diff --git a/android/olm-sdk/src/main/jni/olm_manager.h b/android/olm-sdk/src/main/jni/olm_manager.h deleted file mode 100644 index d11c262..0000000 --- a/android/olm-sdk/src/main/jni/olm_manager.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016 Vector Creations 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 _OLMMANAGER_H -#define _OLMMANAGER_H - -#include "olm_jni.h" -#include "olm/olm.h" - -#define OLM_MANAGER_FUNC_DEF(func_name) FUNC_DEF(OlmManager,func_name) - -#ifdef __cplusplus -extern "C" { -#endif - -JNIEXPORT jstring OLM_MANAGER_FUNC_DEF(getOlmLibVersionJni)(JNIEnv *env, jobject thiz); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/android/olm-sdk/src/main/jni/olm_outbound_group_session.cpp b/android/olm-sdk/src/main/jni/olm_outbound_group_session.cpp deleted file mode 100644 index a22122a..0000000 --- a/android/olm-sdk/src/main/jni/olm_outbound_group_session.cpp +++ /dev/null @@ -1,563 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016 Vector Creations 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. - */ - -#include "olm_outbound_group_session.h" - -using namespace AndroidOlmSdk; - -/** - * Release the session allocation made by initializeOutboundGroupSessionMemory().<br> - * This method MUST be called when java counter part account instance is done. - * - */ -JNIEXPORT void OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(releaseSessionJni)(JNIEnv *env, jobject thiz) -{ - LOGD("## releaseSessionJni(): OutBound group session IN"); - - OlmOutboundGroupSession* sessionPtr = (OlmOutboundGroupSession*)getOutboundGroupSessionInstanceId(env,thiz); - - if (!sessionPtr) - { - LOGE(" ## releaseSessionJni(): failure - invalid outbound group session instance"); - } - else - { - LOGD(" ## releaseSessionJni(): sessionPtr=%p",sessionPtr); - -#ifdef ENABLE_JNI_LOG - size_t retCode = olm_clear_outbound_group_session(sessionPtr); - LOGD(" ## releaseSessionJni(): clear_outbound_group_session=%lu",static_cast<long unsigned int>(retCode)); -#else - olm_clear_outbound_group_session(sessionPtr); -#endif - - LOGD(" ## releaseSessionJni(): free IN"); - free(sessionPtr); - LOGD(" ## releaseSessionJni(): free OUT"); - } -} - -/** - * Initialize a new outbound group session and return it to JAVA side.<br> - * Since a C prt is returned as a jlong, special care will be taken - * to make the cast (OlmOutboundGroupSession* => jlong) platform independent. - * @return the initialized OlmOutboundGroupSession* instance or throw an exception - **/ -JNIEXPORT jlong OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(createNewSessionJni)(JNIEnv *env, jobject thiz) -{ - const char* errorMessage = NULL; - - OlmOutboundGroupSession* sessionPtr = NULL; - size_t sessionSize = 0; - - LOGD("## createNewSessionJni(): outbound group session IN"); - sessionSize = olm_outbound_group_session_size(); - - if (0 == sessionSize) - { - LOGE(" ## createNewSessionJni(): failure - outbound group session size = 0"); - errorMessage = "outbound group session size = 0"; - } - else if (!(sessionPtr = (OlmOutboundGroupSession*)malloc(sessionSize))) - { - LOGE(" ## createNewSessionJni(): failure - outbound group session OOM"); - errorMessage = "outbound group session OOM"; - } - else - { - sessionPtr = olm_outbound_group_session(sessionPtr); - LOGD(" ## createNewSessionJni(): success - outbound group session size=%lu",static_cast<long unsigned int>(sessionSize)); - - // compute random buffer - size_t randomLength = olm_init_outbound_group_session_random_length(sessionPtr); - uint8_t *randomBuffPtr = NULL; - - LOGW(" ## createNewSessionJni(): randomLength=%lu",static_cast<long unsigned int>(randomLength)); - - if ((0 != randomLength) && !setRandomInBuffer(env, &randomBuffPtr, randomLength)) - { - LOGE(" ## createNewSessionJni(): failure - random buffer init"); - errorMessage = "random buffer init"; - } - else - { - if (0 == randomLength) - { - LOGW(" ## createNewSessionJni(): random buffer is not required"); - } - - size_t sessionResult = olm_init_outbound_group_session(sessionPtr, randomBuffPtr, randomLength); - - if (sessionResult == olm_error()) { - errorMessage = (const char *)olm_outbound_group_session_last_error(sessionPtr); - LOGE(" ## createNewSessionJni(): failure - init outbound session creation Msg=%s", errorMessage); - } - else - { - LOGD(" ## createNewSessionJni(): success - result=%lu", static_cast<long unsigned int>(sessionResult)); - } - - // clear the random buffer - memset(randomBuffPtr, 0, randomLength); - free(randomBuffPtr); - } - } - - if (errorMessage) - { - if (sessionPtr) - { - olm_clear_outbound_group_session(sessionPtr); - free(sessionPtr); - } - - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return (jlong)(intptr_t)sessionPtr; -} - -/** - * Return the session identifier. - * An exception is thrown if the operation fails. - * @return the session identifier - */ -JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(sessionIdentifierJni)(JNIEnv *env, jobject thiz) -{ - LOGD("## sessionIdentifierJni(): outbound group session IN"); - - const char* errorMessage = NULL; - OlmOutboundGroupSession *sessionPtr = (OlmOutboundGroupSession*)getOutboundGroupSessionInstanceId(env,thiz); - jbyteArray returnValue = 0; - - if (!sessionPtr) - { - LOGE(" ## sessionIdentifierJni(): failure - invalid outbound group session instance"); - errorMessage = "invalid outbound group session instance"; - } - else - { - // get the size to alloc - size_t lengthSessionId = olm_outbound_group_session_id_length(sessionPtr); - LOGD(" ## sessionIdentifierJni(): outbound group session lengthSessionId=%lu",static_cast<long unsigned int>(lengthSessionId)); - - uint8_t *sessionIdPtr = (uint8_t*)malloc(lengthSessionId*sizeof(uint8_t)); - - if (!sessionIdPtr) - { - LOGE(" ## sessionIdentifierJni(): failure - outbound identifier allocation OOM"); - errorMessage = "outbound identifier allocation OOM"; - } - else - { - size_t result = olm_outbound_group_session_id(sessionPtr, sessionIdPtr, lengthSessionId); - - if (result == olm_error()) - { - errorMessage = reinterpret_cast<const char*>(olm_outbound_group_session_last_error(sessionPtr)); - LOGE(" ## sessionIdentifierJni(): failure - outbound group session identifier failure Msg=%s", errorMessage); - } - else - { - returnValue = env->NewByteArray(result); - env->SetByteArrayRegion(returnValue, 0 , result, (jbyte*)sessionIdPtr); - - LOGD(" ## sessionIdentifierJni(): success - outbound group session identifier result=%lu sessionId= %.*s",static_cast<long unsigned int>(result), static_cast<int>(result), reinterpret_cast<char*>(sessionIdPtr)); - } - - // free alloc - free(sessionIdPtr); - } - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return returnValue; -} - - -/** - * Get the current message index for this session.<br> - * Each message is sent with an increasing index, this - * method returns the index for the next message. - * An exception is thrown if the operation fails. - * @return current session index - */ -JNIEXPORT jint OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(messageIndexJni)(JNIEnv *env, jobject thiz) -{ - OlmOutboundGroupSession *sessionPtr = NULL; - jint indexRetValue = 0; - - LOGD("## messageIndexJni(): IN"); - - if (!(sessionPtr = (OlmOutboundGroupSession*)getOutboundGroupSessionInstanceId(env,thiz))) - { - LOGE(" ## messageIndexJni(): failure - invalid outbound group session instance"); - } - else - { - indexRetValue = static_cast<jint>(olm_outbound_group_session_message_index(sessionPtr)); - } - - LOGD(" ## messageIndexJni(): success - index=%d",indexRetValue); - - return indexRetValue; -} - -/** - * Return the session key. - * An exception is thrown if the operation fails. - * @return the session key - */ -JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(sessionKeyJni)(JNIEnv *env, jobject thiz) -{ - LOGD("## sessionKeyJni(): outbound group session IN"); - - const char* errorMessage = NULL; - OlmOutboundGroupSession *sessionPtr = (OlmOutboundGroupSession*)getOutboundGroupSessionInstanceId(env,thiz); - jbyteArray returnValue = 0; - - if (!sessionPtr) - { - LOGE(" ## sessionKeyJni(): failure - invalid outbound group session instance"); - errorMessage = "invalid outbound group session instance"; - } - else - { - // get the size to alloc - size_t sessionKeyLength = olm_outbound_group_session_key_length(sessionPtr); - LOGD(" ## sessionKeyJni(): sessionKeyLength=%lu",static_cast<long unsigned int>(sessionKeyLength)); - - uint8_t *sessionKeyPtr = (uint8_t*)malloc(sessionKeyLength*sizeof(uint8_t)); - - if (!sessionKeyPtr) - { - LOGE(" ## sessionKeyJni(): failure - session key allocation OOM"); - errorMessage = "session key allocation OOM"; - } - else - { - size_t result = olm_outbound_group_session_key(sessionPtr, sessionKeyPtr, sessionKeyLength); - - if (result == olm_error()) - { - errorMessage = (const char *)olm_outbound_group_session_last_error(sessionPtr); - LOGE(" ## sessionKeyJni(): failure - session key failure Msg=%s", errorMessage); - } - else - { - LOGD(" ## sessionKeyJni(): success - outbound group session key result=%lu sessionKey=%.*s",static_cast<long unsigned int>(result), static_cast<int>(result), reinterpret_cast<char*>(sessionKeyPtr)); - - returnValue = env->NewByteArray(result); - env->SetByteArrayRegion(returnValue, 0 , result, (jbyte*)sessionKeyPtr); - } - - // free alloc - free(sessionKeyPtr); - } - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return returnValue; -} - -/** - * Encrypt a bytes buffer messages. - * An exception is thrown if the operation fails. - * @param aClearMsgBuffer the message to encode - * @return the encoded message - */ -JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aClearMsgBuffer) -{ - LOGD("## encryptMessageJni(): IN"); - - const char* errorMessage = NULL; - jbyteArray encryptedMsgRet = 0; - - OlmOutboundGroupSession *sessionPtr = NULL; - jbyte* clearMsgPtr = NULL; - jboolean clearMsgIsCopied = JNI_FALSE; - - if (!(sessionPtr = (OlmOutboundGroupSession*)getOutboundGroupSessionInstanceId(env,thiz))) - { - LOGE(" ## encryptMessageJni(): failure - invalid outbound group session ptr=NULL"); - errorMessage = "invalid outbound group session ptr=NULL"; - } - else if (!aClearMsgBuffer) - { - LOGE(" ## encryptMessageJni(): failure - invalid clear message"); - errorMessage = "invalid clear message"; - } - else if (!(clearMsgPtr = env->GetByteArrayElements(aClearMsgBuffer, &clearMsgIsCopied))) - { - LOGE(" ## encryptMessageJni(): failure - clear message JNI allocation OOM"); - errorMessage = "clear message JNI allocation OOM"; - } - else - { - // get clear message length - size_t clearMsgLength = (size_t)env->GetArrayLength(aClearMsgBuffer); - LOGD(" ## encryptMessageJni(): clearMsgLength=%lu",static_cast<long unsigned int>(clearMsgLength)); - - // compute max encrypted length - size_t encryptedMsgLength = olm_group_encrypt_message_length(sessionPtr,clearMsgLength); - uint8_t *encryptedMsgPtr = (uint8_t*)malloc(encryptedMsgLength*sizeof(uint8_t)); - - if (!encryptedMsgPtr) - { - LOGE(" ## encryptMessageJni(): failure - encryptedMsgPtr buffer OOM"); - errorMessage = "encryptedMsgPtr buffer OOM"; - } - else - { - LOGD(" ## encryptMessageJni(): estimated encryptedMsgLength=%lu",static_cast<long unsigned int>(encryptedMsgLength)); - - size_t encryptedLength = olm_group_encrypt(sessionPtr, - (uint8_t*)clearMsgPtr, - clearMsgLength, - encryptedMsgPtr, - encryptedMsgLength); - - - if (encryptedLength == olm_error()) - { - errorMessage = olm_outbound_group_session_last_error(sessionPtr); - LOGE(" ## encryptMessageJni(): failure - olm_group_decrypt_max_plaintext_length Msg=%s", errorMessage); - } - else - { - LOGD(" ## encryptMessageJni(): encrypted returnedLg=%lu plainTextMsgPtr=%.*s",static_cast<long unsigned int>(encryptedLength), static_cast<int>(encryptedLength), reinterpret_cast<char*>(encryptedMsgPtr)); - - encryptedMsgRet = env->NewByteArray(encryptedLength); - env->SetByteArrayRegion(encryptedMsgRet, 0 , encryptedLength, (jbyte*)encryptedMsgPtr); - } - - free(encryptedMsgPtr); - } - } - - // free alloc - if (clearMsgPtr) - { - if (clearMsgIsCopied) - { - memset(clearMsgPtr, 0, (size_t)env->GetArrayLength(aClearMsgBuffer)); - } - env->ReleaseByteArrayElements(aClearMsgBuffer, clearMsgPtr, JNI_ABORT); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return encryptedMsgRet; -} - -/** - * Serialize and encrypt session instance into a base64 string.<br> - * An exception is thrown if the operation fails. - * @param aKey key used to encrypt the serialized session data - * @return a base64 string if operation succeed, null otherwise - **/ -JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKeyBuffer) -{ - const char* errorMessage = NULL; - jbyteArray returnValue = 0; - - jbyte* keyPtr = NULL; - jboolean keyWasCopied = JNI_FALSE; - OlmOutboundGroupSession* sessionPtr = NULL; - - LOGD("## outbound group session serializeJni(): IN"); - - if (!(sessionPtr = (OlmOutboundGroupSession*)getOutboundGroupSessionInstanceId(env,thiz))) - { - LOGE(" ## serializeJni(): failure - invalid session ptr"); - errorMessage = "invalid session ptr"; - } - else if (!aKeyBuffer) - { - LOGE(" ## serializeJni(): failure - invalid key"); - errorMessage = "invalid key"; - } - else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, &keyWasCopied))) - { - LOGE(" ## serializeJni(): failure - keyPtr JNI allocation OOM"); - errorMessage = "keyPtr JNI allocation OOM"; - } - else - { - size_t pickledLength = olm_pickle_outbound_group_session_length(sessionPtr); - size_t keyLength = (size_t)env->GetArrayLength(aKeyBuffer); - LOGD(" ## serializeJni(): pickledLength=%lu keyLength=%lu",static_cast<long unsigned int>(pickledLength), static_cast<long unsigned int>(keyLength)); - - void *pickledPtr = malloc(pickledLength*sizeof(uint8_t)); - - if(!pickledPtr) - { - LOGE(" ## serializeJni(): failure - pickledPtr buffer OOM"); - errorMessage = "pickledPtr buffer OOM"; - } - else - { - size_t result = olm_pickle_outbound_group_session(sessionPtr, - (void const *)keyPtr, - keyLength, - (void*)pickledPtr, - pickledLength); - if (result == olm_error()) - { - errorMessage = olm_outbound_group_session_last_error(sessionPtr); - LOGE(" ## serializeJni(): failure - olm_pickle_outbound_group_session() Msg=%s", errorMessage); - } - else - { - LOGD(" ## serializeJni(): success - result=%lu pickled=%.*s", static_cast<long unsigned int>(result), static_cast<int>(result), static_cast<char*>(pickledPtr)); - - returnValue = env->NewByteArray(pickledLength); - env->SetByteArrayRegion(returnValue, 0 , pickledLength, (jbyte*)pickledPtr); - } - } - - free(pickledPtr); - } - - // free alloc - if (keyPtr) - { - if (keyWasCopied) { - memset(keyPtr, 0, (size_t)env->GetArrayLength(aKeyBuffer)); - } - env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return returnValue; -} - -/** - * Allocate a new session and initialize it with the serialisation data.<br> - * An exception is thrown if the operation fails. - * @param aSerializedData the session serialisation buffer - * @param aKey the key used to encrypt the serialized account data - * @return the deserialized session - **/ -JNIEXPORT jlong OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(deserializeJni)(JNIEnv *env, jobject thiz, jbyteArray aSerializedDataBuffer, jbyteArray aKeyBuffer) -{ - const char* errorMessage = NULL; - size_t sessionSize = olm_outbound_group_session_size(); - OlmOutboundGroupSession* sessionPtr = NULL; - - jbyte* keyPtr = NULL; - jboolean keyWasCopied = JNI_FALSE; - jbyte* pickledPtr = NULL; - - LOGD("## deserializeJni(): IN"); - - if (!sessionSize) - { - LOGE(" ## deserializeJni(): failure - outbound group session size = 0"); - errorMessage = "outbound group session size = 0"; - } - else if (!(sessionPtr = (OlmOutboundGroupSession*)malloc(sessionSize))) - { - LOGE(" ## deserializeJni(): failure - session failure OOM"); - errorMessage = "session failure OOM"; - } - else if (!aKeyBuffer) - { - LOGE(" ## deserializeJni(): failure - invalid key"); - errorMessage = "invalid key"; - } - else if (!aSerializedDataBuffer) - { - LOGE(" ## deserializeJni(): failure - serialized data"); - errorMessage = "invalid serialized data"; - } - else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, &keyWasCopied))) - { - LOGE(" ## deserializeJni(): failure - keyPtr JNI allocation OOM"); - errorMessage = "keyPtr JNI allocation OOM"; - } - else if (!(pickledPtr = env->GetByteArrayElements(aSerializedDataBuffer, 0))) - { - LOGE(" ## deserializeJni(): failure - pickledPtr JNI allocation OOM"); - errorMessage = "pickledPtr JNI allocation OOM"; - } - else - { - sessionPtr = olm_outbound_group_session(sessionPtr); - size_t pickledLength = (size_t)env->GetArrayLength(aSerializedDataBuffer); - size_t keyLength = (size_t)env->GetArrayLength(aKeyBuffer); - LOGD(" ## deserializeJni(): pickledLength=%lu keyLength=%lu",static_cast<long unsigned int>(pickledLength), static_cast<long unsigned int>(keyLength)); - LOGD(" ## deserializeJni(): pickled=%.*s", static_cast<int>(pickledLength), (char const *)pickledPtr); - - size_t result = olm_unpickle_outbound_group_session(sessionPtr, - (void const *)keyPtr, - keyLength, - (void*)pickledPtr, - pickledLength); - if (result == olm_error()) - { - errorMessage = olm_outbound_group_session_last_error(sessionPtr); - LOGE(" ## deserializeJni(): failure - olm_unpickle_outbound_group_session() Msg=%s", errorMessage); - } - else - { - LOGD(" ## deserializeJni(): success - result=%lu ", static_cast<long unsigned int>(result)); - } - } - - // free alloc - if (keyPtr) - { - if (keyWasCopied) { - memset(keyPtr, 0, (size_t)env->GetArrayLength(aKeyBuffer)); - } - env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT); - } - - if (pickledPtr) - { - env->ReleaseByteArrayElements(aSerializedDataBuffer, pickledPtr, JNI_ABORT); - } - - if (errorMessage) - { - if (sessionPtr) - { - olm_clear_outbound_group_session(sessionPtr); - free(sessionPtr); - } - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return (jlong)(intptr_t)sessionPtr; -} - diff --git a/android/olm-sdk/src/main/jni/olm_outbound_group_session.h b/android/olm-sdk/src/main/jni/olm_outbound_group_session.h deleted file mode 100644 index 051dd2f..0000000 --- a/android/olm-sdk/src/main/jni/olm_outbound_group_session.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016 Vector Creations 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 _OLMOUTBOUND_GROUP_SESSION_H -#define _OLMOUTBOUND_GROUP_SESSION_H - -#include "olm_jni.h" -#include "olm/olm.h" -#include "olm/outbound_group_session.h" - -#define OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(func_name) FUNC_DEF(OlmOutboundGroupSession,func_name) - -#ifdef __cplusplus -extern "C" { -#endif - -// session creation/destruction -JNIEXPORT void OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(releaseSessionJni)(JNIEnv *env, jobject thiz); -JNIEXPORT jlong OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(createNewSessionJni)(JNIEnv *env, jobject thiz); - -JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(sessionIdentifierJni)(JNIEnv *env, jobject thiz); -JNIEXPORT jint OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(messageIndexJni)(JNIEnv *env, jobject thiz); -JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(sessionKeyJni)(JNIEnv *env, jobject thiz); - -JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aClearMsgBuffer); - -// serialization -JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKey); -JNIEXPORT jlong OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(deserializeJni)(JNIEnv *env, jobject thiz, jbyteArray aSerializedData, jbyteArray aKey); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/android/olm-sdk/src/main/jni/olm_pk.cpp b/android/olm-sdk/src/main/jni/olm_pk.cpp deleted file mode 100644 index c528342..0000000 --- a/android/olm-sdk/src/main/jni/olm_pk.cpp +++ /dev/null @@ -1,992 +0,0 @@ -/* - * 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. - */ - -#include "olm_pk.h" - -#include "olm/olm.h" - -using namespace AndroidOlmSdk; - -OlmPkEncryption * initializePkEncryptionMemory() -{ - size_t encryptionSize = olm_pk_encryption_size(); - OlmPkEncryption *encryptionPtr = (OlmPkEncryption *)malloc(encryptionSize); - - if (encryptionPtr) - { - // init encryption object - encryptionPtr = olm_pk_encryption(encryptionPtr); - LOGD( - "## initializePkEncryptionMemory(): success - OLM encryption size=%lu", - static_cast<long unsigned int>(encryptionSize) - ); - } - else - { - LOGE("## initializePkEncryptionMemory(): failure - OOM"); - } - - return encryptionPtr; -} - -JNIEXPORT jlong OLM_PK_ENCRYPTION_FUNC_DEF(createNewPkEncryptionJni)(JNIEnv *env, jobject thiz) -{ - const char* errorMessage = NULL; - OlmPkEncryption *encryptionPtr = initializePkEncryptionMemory(); - - // init encryption memory allocation - if (!encryptionPtr) - { - LOGE("## createNewPkEncryptionJni(): failure - init encryption OOM"); - errorMessage = "init encryption OOM"; - } - else - { - LOGD("## createNewPkEncryptionJni(): success - OLM encryption created"); - LOGD( - "## createNewPkEncryptionJni(): encryptionPtr=%p (jlong)(intptr_t)encryptionPtr=%lld", - encryptionPtr, (jlong)(intptr_t)encryptionPtr - ); - } - - if (errorMessage) - { - // release the allocated data - if (encryptionPtr) - { - olm_clear_pk_encryption(encryptionPtr); - free(encryptionPtr); - } - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return (jlong)(intptr_t)encryptionPtr; -} - -JNIEXPORT void OLM_PK_ENCRYPTION_FUNC_DEF(releasePkEncryptionJni)(JNIEnv *env, jobject thiz) -{ - LOGD("## releasePkEncryptionJni(): IN"); - - OlmPkEncryption* encryptionPtr = getPkEncryptionInstanceId(env, thiz); - - if (!encryptionPtr) - { - LOGE(" ## releasePkEncryptionJni(): failure - invalid Encryption ptr=NULL"); - } - else - { - LOGD(" ## releasePkEncryptionJni(): encryptionPtr=%p", encryptionPtr); - olm_clear_pk_encryption(encryptionPtr); - - LOGD(" ## releasePkEncryptionJni(): IN"); - // even if free(NULL) does not crash, logs are performed for debug - // purpose - free(encryptionPtr); - LOGD(" ## releasePkEncryptionJni(): OUT"); - } -} - -JNIEXPORT void OLM_PK_ENCRYPTION_FUNC_DEF(setRecipientKeyJni)( - JNIEnv *env, jobject thiz, jbyteArray aKeyBuffer -) { - const char *errorMessage = NULL; - jbyte *keyPtr = NULL; - - OlmPkEncryption *encryptionPtr = getPkEncryptionInstanceId(env, thiz); - - if (!encryptionPtr) - { - LOGE(" ## pkSetRecipientKeyJni(): failure - invalid Encryption ptr=NULL"); - } - else if (!aKeyBuffer) - { - LOGE(" ## pkSetRecipientKeyJni(): failure - invalid key"); - errorMessage = "invalid key"; - } - else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, 0))) - { - LOGE(" ## pkSetRecipientKeyJni(): failure - key JNI allocation OOM"); - errorMessage = "key JNI allocation OOM"; - } - else - { - if (olm_pk_encryption_set_recipient_key(encryptionPtr, keyPtr, (size_t)env->GetArrayLength(aKeyBuffer)) == olm_error()) - { - errorMessage = olm_pk_encryption_last_error(encryptionPtr); - LOGE( - " ## pkSetRecipientKeyJni(): failure - olm_pk_encryption_set_recipient_key Msg=%s", - errorMessage - ); - } - } - - if (keyPtr) - { - env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } -} - -JNIEXPORT jbyteArray OLM_PK_ENCRYPTION_FUNC_DEF(encryptJni)( - JNIEnv *env, jobject thiz, jbyteArray aPlaintextBuffer, jobject aEncryptedMsg -) { - jbyteArray encryptedMsgRet = 0; - const char* errorMessage = NULL; - jbyte *plaintextPtr = NULL; - jboolean plaintextIsCopied = JNI_FALSE; - - OlmPkEncryption *encryptionPtr = getPkEncryptionInstanceId(env, thiz); - jclass encryptedMsgJClass = 0; - jfieldID macFieldId; - jfieldID ephemeralFieldId; - - if (!encryptionPtr) - { - LOGE(" ## pkEncryptJni(): failure - invalid Encryption ptr=NULL"); - } - else if (!aPlaintextBuffer) - { - LOGE(" ## pkEncryptJni(): failure - invalid clear message"); - errorMessage = "invalid clear message"; - } - else if (!(plaintextPtr = env->GetByteArrayElements(aPlaintextBuffer, &plaintextIsCopied))) - { - LOGE(" ## pkEncryptJni(): failure - plaintext JNI allocation OOM"); - errorMessage = "plaintext JNI allocation OOM"; - } - else if (!(encryptedMsgJClass = env->GetObjectClass(aEncryptedMsg))) - { - LOGE(" ## pkEncryptJni(): failure - unable to get encrypted message class"); - errorMessage = "unable to get encrypted message class"; - } - else if (!(macFieldId = env->GetFieldID(encryptedMsgJClass, "mMac", "Ljava/lang/String;"))) - { - LOGE("## pkEncryptJni(): failure - unable to get MAC field"); - errorMessage = "unable to get MAC field"; - } - else if (!(ephemeralFieldId = env->GetFieldID(encryptedMsgJClass, "mEphemeralKey", "Ljava/lang/String;"))) - { - LOGE("## pkEncryptJni(): failure - unable to get ephemeral key field"); - errorMessage = "unable to get ephemeral key field"; - } - else - { - size_t plaintextLength = (size_t)env->GetArrayLength(aPlaintextBuffer); - size_t ciphertextLength = olm_pk_ciphertext_length(encryptionPtr, plaintextLength); - size_t macLength = olm_pk_mac_length(encryptionPtr); - size_t ephemeralLength = olm_pk_key_length(); - uint8_t *ciphertextPtr = NULL, *macPtr = NULL, *ephemeralPtr = NULL; - size_t randomLength = olm_pk_encrypt_random_length(encryptionPtr); - uint8_t *randomBuffPtr = NULL; - LOGD("## pkEncryptJni(): randomLength=%lu",static_cast<long unsigned int>(randomLength)); - if (!(ciphertextPtr = (uint8_t*)malloc(ciphertextLength))) - { - LOGE("## pkEncryptJni(): failure - ciphertext JNI allocation OOM"); - errorMessage = "ciphertext JNI allocation OOM"; - } - else if (!(macPtr = (uint8_t*)malloc(macLength + 1))) - { - LOGE("## pkEncryptJni(): failure - MAC JNI allocation OOM"); - errorMessage = "MAC JNI allocation OOM"; - } - else if (!(ephemeralPtr = (uint8_t*)malloc(ephemeralLength + 1))) - { - LOGE("## pkEncryptJni(): failure: ephemeral key JNI allocation OOM"); - errorMessage = "ephemeral JNI allocation OOM"; - } - else if (!setRandomInBuffer(env, &randomBuffPtr, randomLength)) - { - LOGE("## pkEncryptJni(): failure - random buffer init"); - errorMessage = "random buffer init"; - } - else - { - macPtr[macLength] = '\0'; - ephemeralPtr[ephemeralLength] = '\0'; - - size_t returnValue = olm_pk_encrypt( - encryptionPtr, - plaintextPtr, plaintextLength, - ciphertextPtr, ciphertextLength, - macPtr, macLength, - ephemeralPtr, ephemeralLength, - randomBuffPtr, randomLength - ); - - if (returnValue == olm_error()) - { - errorMessage = olm_pk_encryption_last_error(encryptionPtr); - LOGE("## pkEncryptJni(): failure - olm_pk_encrypt Msg=%s", errorMessage); - } - else - { - encryptedMsgRet = env->NewByteArray(ciphertextLength); - env->SetByteArrayRegion( - encryptedMsgRet, 0, ciphertextLength, (jbyte*)ciphertextPtr - ); - - jstring macStr = env->NewStringUTF((char*)macPtr); - env->SetObjectField(aEncryptedMsg, macFieldId, macStr); - jstring ephemeralStr = env->NewStringUTF((char*)ephemeralPtr); - env->SetObjectField(aEncryptedMsg, ephemeralFieldId, ephemeralStr); - } - } - - if (randomBuffPtr) - { - memset(randomBuffPtr, 0, randomLength); - free(randomBuffPtr); - } - if (ephemeralPtr) - { - free(ephemeralPtr); - } - if (macPtr) - { - free(macPtr); - } - if (ciphertextPtr) - { - free(ciphertextPtr); - } - } - - if (plaintextPtr) - { - if (plaintextIsCopied) - { - memset(plaintextPtr, 0, (size_t)env->GetArrayLength(aPlaintextBuffer)); - } - env->ReleaseByteArrayElements(aPlaintextBuffer, plaintextPtr, JNI_ABORT); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return encryptedMsgRet; -} - -OlmPkDecryption * initializePkDecryptionMemory() -{ - size_t decryptionSize = olm_pk_decryption_size(); - OlmPkDecryption *decryptionPtr = (OlmPkDecryption *)malloc(decryptionSize); - - if (decryptionPtr) - { - // init decryption object - decryptionPtr = olm_pk_decryption(decryptionPtr); - LOGD( - "## initializePkDecryptionMemory(): success - OLM decryption size=%lu", - static_cast<long unsigned int>(decryptionSize) - ); - } - else - { - LOGE("## initializePkDecryptionMemory(): failure - OOM"); - } - - return decryptionPtr; -} - -JNIEXPORT jlong OLM_PK_DECRYPTION_FUNC_DEF(createNewPkDecryptionJni)(JNIEnv *env, jobject thiz) -{ - const char* errorMessage = NULL; - OlmPkDecryption *decryptionPtr = initializePkDecryptionMemory(); - - // init encryption memory allocation - if (!decryptionPtr) - { - LOGE("## createNewPkDecryptionJni(): failure - init decryption OOM"); - errorMessage = "init decryption OOM"; - } - else - { - LOGD("## createNewPkDecryptionJni(): success - OLM decryption created"); - LOGD( - "## createNewPkDecryptionJni(): decryptionPtr=%p (jlong)(intptr_t)decryptionPtr=%lld", - decryptionPtr, (jlong)(intptr_t)decryptionPtr - ); - } - - if (errorMessage) - { - // release the allocated data - if (decryptionPtr) - { - olm_clear_pk_decryption(decryptionPtr); - free(decryptionPtr); - } - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return (jlong)(intptr_t)decryptionPtr; -} - -JNIEXPORT void OLM_PK_DECRYPTION_FUNC_DEF(releasePkDecryptionJni)(JNIEnv *env, jobject thiz) -{ - LOGD("## releasePkDecryptionJni(): IN"); - - OlmPkDecryption* decryptionPtr = getPkDecryptionInstanceId(env, thiz); - - if (!decryptionPtr) - { - LOGE(" ## releasePkDecryptionJni(): failure - invalid Decryption ptr=NULL"); - } - else - { - LOGD(" ## releasePkDecryptionJni(): decryptionPtr=%p", encryptionPtr); - olm_clear_pk_decryption(decryptionPtr); - - LOGD(" ## releasePkDecryptionJni(): IN"); - // even if free(NULL) does not crash, logs are performed for debug - // purpose - free(decryptionPtr); - LOGD(" ## releasePkDecryptionJni(): OUT"); - } -} - -JNIEXPORT jint OLM_PK_DECRYPTION_FUNC_DEF(privateKeyLength)(JNIEnv *env, jobject thiz) -{ - return (jint) olm_pk_private_key_length(); -} - -JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(setPrivateKeyJni)(JNIEnv *env, jobject thiz, jbyteArray key) -{ - jbyteArray publicKeyRet = 0; - jbyte *keyPtr = NULL; - jboolean keyWasCopied = JNI_FALSE; - - const char* errorMessage = NULL; - - OlmPkDecryption* decryptionPtr = getPkDecryptionInstanceId(env, thiz); - - if (!decryptionPtr) - { - LOGE(" ## pkSetPrivateKeyJni(): failure - invalid Decryption ptr=NULL"); - } - else if (!key) - { - LOGE(" ## pkSetPrivateKeyJni(): failure - invalid key"); - errorMessage = "invalid key"; - } - else if (!(keyPtr = env->GetByteArrayElements(key, &keyWasCopied))) - { - LOGE(" ## pkSetPrivateKeyJni(): failure - key JNI allocation OOM"); - errorMessage = "key JNI allocation OOM"; - } - else - { - size_t publicKeyLength = olm_pk_key_length(); - uint8_t *publicKeyPtr = NULL; - size_t keyLength = (size_t)env->GetArrayLength(key); - if (!(publicKeyPtr = (uint8_t*)malloc(publicKeyLength))) - { - LOGE("## pkSetPrivateKeyJni(): failure - public key JNI allocation OOM"); - errorMessage = "public key JNI allocation OOM"; - } - else - { - size_t returnValue = olm_pk_key_from_private( - decryptionPtr, - publicKeyPtr, publicKeyLength, - keyPtr, keyLength - ); - if (returnValue == olm_error()) - { - errorMessage = olm_pk_decryption_last_error(decryptionPtr); - LOGE(" ## pkSetPrivateKeyJni(): failure - olm_pk_key_from_private Msg=%s", errorMessage); - } - else - { - publicKeyRet = env->NewByteArray(publicKeyLength); - env->SetByteArrayRegion( - publicKeyRet, 0, publicKeyLength, (jbyte*)publicKeyPtr - ); - } - } - } - - if (keyPtr) - { - if (keyWasCopied) - { - memset(keyPtr, 0, (size_t)env->GetArrayLength(key)); - } - env->ReleaseByteArrayElements(key, keyPtr, JNI_ABORT); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return publicKeyRet; -} - -JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(generateKeyJni)(JNIEnv *env, jobject thiz) -{ - size_t randomLength = olm_pk_private_key_length(); - uint8_t *randomBuffPtr = NULL; - - jbyteArray publicKeyRet = 0; - uint8_t *publicKeyPtr = NULL; - size_t publicKeyLength = olm_pk_key_length(); - const char* errorMessage = NULL; - - OlmPkDecryption *decryptionPtr = getPkDecryptionInstanceId(env, thiz); - - if (!decryptionPtr) - { - LOGE(" ## pkGenerateKeyJni(): failure - invalid Decryption ptr=NULL"); - errorMessage = "invalid Decryption ptr=NULL"; - } - else if (!setRandomInBuffer(env, &randomBuffPtr, randomLength)) - { - LOGE("## pkGenerateKeyJni(): failure - random buffer init"); - errorMessage = "random buffer init"; - } - else if (!(publicKeyPtr = static_cast<uint8_t*>(malloc(publicKeyLength)))) - { - LOGE("## pkGenerateKeyJni(): failure - public key allocation OOM"); - errorMessage = "public key allocation OOM"; - } - else - { - if (olm_pk_key_from_private(decryptionPtr, publicKeyPtr, publicKeyLength, randomBuffPtr, randomLength) == olm_error()) - { - errorMessage = olm_pk_decryption_last_error(decryptionPtr); - LOGE("## pkGenerateKeyJni(): failure - olm_pk_generate_key Msg=%s", errorMessage); - } - else - { - publicKeyRet = env->NewByteArray(publicKeyLength); - env->SetByteArrayRegion(publicKeyRet, 0, publicKeyLength, (jbyte*)publicKeyPtr); - LOGD("## pkGenerateKeyJni(): public key generated"); - } - } - - if (randomBuffPtr) - { - memset(randomBuffPtr, 0, randomLength); - free(randomBuffPtr); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return publicKeyRet; -} - -JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(privateKeyJni)(JNIEnv *env, jobject thiz) -{ - jbyteArray privateKeyRet = 0; - - const char* errorMessage = NULL; - - OlmPkDecryption* decryptionPtr = getPkDecryptionInstanceId(env, thiz); - - if (!decryptionPtr) - { - LOGE(" ## pkPrivateKeyJni(): failure - invalid Decryption ptr=NULL"); - } - else - { - size_t privateKeyLength = olm_pk_private_key_length(); - uint8_t *privateKeyPtr = NULL; - if (!(privateKeyPtr = (uint8_t*)malloc(privateKeyLength))) - { - LOGE("## pkPrivateKeyJni(): failure - private key JNI allocation OOM"); - errorMessage = "private key JNI allocation OOM"; - } - else - { - size_t returnValue = olm_pk_get_private_key( - decryptionPtr, - privateKeyPtr, privateKeyLength - ); - if (returnValue == olm_error()) - { - errorMessage = olm_pk_decryption_last_error(decryptionPtr); - LOGE(" ## pkPrivateKeyJni(): failure - olm_pk_get_private_key Msg=%s", errorMessage); - } - else - { - privateKeyRet = env->NewByteArray(privateKeyLength); - env->SetByteArrayRegion( - privateKeyRet, 0, privateKeyLength, (jbyte*)privateKeyPtr - ); - memset(privateKeyPtr, 0, privateKeyLength); - } - } - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return privateKeyRet; -} - -JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(decryptJni)( - JNIEnv *env, jobject thiz, jobject aEncryptedMsg -) { - const char* errorMessage = NULL; - OlmPkDecryption *decryptionPtr = getPkDecryptionInstanceId(env, thiz); - - jclass encryptedMsgJClass = 0; - jstring ciphertextJstring = 0; - jstring macJstring = 0; - jstring ephemeralKeyJstring = 0; - jfieldID ciphertextFieldId; - jfieldID macFieldId; - jfieldID ephemeralKeyFieldId; - - const char *ciphertextPtr = NULL; - const char *macPtr = NULL; - const char *ephemeralKeyPtr = NULL; - - jbyteArray decryptedMsgRet = 0; - - if (!decryptionPtr) - { - LOGE(" ## pkDecryptJni(): failure - invalid Decryption ptr=NULL"); - errorMessage = "invalid Decryption ptr=NULL"; - } - else if (!aEncryptedMsg) - { - LOGE(" ## pkDecryptJni(): failure - invalid encrypted message"); - errorMessage = "invalid encrypted message"; - } - else if (!(encryptedMsgJClass = env->GetObjectClass(aEncryptedMsg))) - { - LOGE("## pkDecryptJni(): failure - unable to get encrypted message class"); - errorMessage = "unable to get encrypted message class"; - } - else if (!(ciphertextFieldId = env->GetFieldID(encryptedMsgJClass,"mCipherText","Ljava/lang/String;"))) - { - LOGE("## pkDecryptJni(): failure - unable to get message field"); - errorMessage = "unable to get message field"; - } - else if (!(ciphertextJstring = (jstring)env->GetObjectField(aEncryptedMsg, ciphertextFieldId))) - { - LOGE("## pkDecryptJni(): failure - no ciphertext"); - errorMessage = "no ciphertext"; - } - else if (!(ciphertextPtr = env->GetStringUTFChars(ciphertextJstring, 0))) - { - LOGE("## pkDecryptJni(): failure - ciphertext JNI allocation OOM"); - errorMessage = "ciphertext JNI allocation OOM"; - } - else if (!(ciphertextJstring = (jstring)env->GetObjectField(aEncryptedMsg, ciphertextFieldId))) - { - LOGE("## pkDecryptJni(): failure - no ciphertext"); - errorMessage = "no ciphertext"; - } - else if (!(ciphertextPtr = env->GetStringUTFChars(ciphertextJstring, 0))) - { - LOGE("## decryptMessageJni(): failure - ciphertext JNI allocation OOM"); - errorMessage = "ciphertext JNI allocation OOM"; - } - else if (!(macFieldId = env->GetFieldID(encryptedMsgJClass,"mMac","Ljava/lang/String;"))) - { - LOGE("## pkDecryptJni(): failure - unable to get MAC field"); - errorMessage = "unable to get MAC field"; - } - else if (!(macJstring = (jstring)env->GetObjectField(aEncryptedMsg, macFieldId))) - { - LOGE("## pkDecryptJni(): failure - no MAC"); - errorMessage = "no MAC"; - } - else if (!(macPtr = env->GetStringUTFChars(macJstring, 0))) - { - LOGE("## pkDecryptJni(): failure - MAC JNI allocation OOM"); - errorMessage = "ciphertext JNI allocation OOM"; - } - else if (!(ephemeralKeyFieldId = env->GetFieldID(encryptedMsgJClass,"mEphemeralKey","Ljava/lang/String;"))) - { - LOGE("## pkDecryptJni(): failure - unable to get ephemeral key field"); - errorMessage = "unable to get ephemeral key field"; - } - else if (!(ephemeralKeyJstring = (jstring)env->GetObjectField(aEncryptedMsg, ephemeralKeyFieldId))) - { - LOGE("## pkDecryptJni(): failure - no ephemeral key"); - errorMessage = "no ephemeral key"; - } - else if (!(ephemeralKeyPtr = env->GetStringUTFChars(ephemeralKeyJstring, 0))) - { - LOGE("## pkDecryptJni(): failure - ephemeral key JNI allocation OOM"); - errorMessage = "ephemeral key JNI allocation OOM"; - } - else - { - size_t maxPlaintextLength = olm_pk_max_plaintext_length( - decryptionPtr, - (size_t)env->GetStringUTFLength(ciphertextJstring) - ); - uint8_t *plaintextPtr = NULL; - uint8_t *tempCiphertextPtr = NULL; - size_t ciphertextLength = (size_t)env->GetStringUTFLength(ciphertextJstring); - if (!(plaintextPtr = (uint8_t*)malloc(maxPlaintextLength))) - { - LOGE("## pkDecryptJni(): failure - plaintext JNI allocation OOM"); - errorMessage = "plaintext JNI allocation OOM"; - } - else if (!(tempCiphertextPtr = (uint8_t*)malloc(ciphertextLength))) - { - LOGE("## pkDecryptJni(): failure - temp ciphertext JNI allocation OOM"); - } - else - { - memcpy(tempCiphertextPtr, ciphertextPtr, ciphertextLength); - size_t plaintextLength = olm_pk_decrypt( - decryptionPtr, - ephemeralKeyPtr, (size_t)env->GetStringUTFLength(ephemeralKeyJstring), - macPtr, (size_t)env->GetStringUTFLength(macJstring), - tempCiphertextPtr, ciphertextLength, - plaintextPtr, maxPlaintextLength - ); - if (plaintextLength == olm_error()) - { - errorMessage = olm_pk_decryption_last_error(decryptionPtr); - LOGE("## pkDecryptJni(): failure - olm_pk_decrypt Msg=%s", errorMessage); - } - else - { - decryptedMsgRet = env->NewByteArray(plaintextLength); - env->SetByteArrayRegion(decryptedMsgRet, 0, plaintextLength, (jbyte*)plaintextPtr); - LOGD( - "## pkDecryptJni(): success returnedLg=%lu OK", - static_cast<long unsigned int>(plaintextLength) - ); - } - } - - if (tempCiphertextPtr) - { - free(tempCiphertextPtr); - } - if (plaintextPtr) - { - memset(plaintextPtr, 0, maxPlaintextLength); - free(plaintextPtr); - } - } - - if (ciphertextPtr) - { - env->ReleaseStringUTFChars(ciphertextJstring, ciphertextPtr); - } - if (macPtr) - { - env->ReleaseStringUTFChars(macJstring, macPtr); - } - if (ephemeralKeyPtr) - { - env->ReleaseStringUTFChars(ephemeralKeyJstring, ephemeralKeyPtr); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return decryptedMsgRet; -} - -OlmPkSigning * initializePkSigningMemory() -{ - size_t signingSize = olm_pk_signing_size(); - OlmPkSigning *signingPtr = (OlmPkSigning *)malloc(signingSize); - - if (signingPtr) - { - // init encryption object - signingPtr = olm_pk_signing(signingPtr); - LOGD( - "## initializePkSigningMemory(): success - OLM signing size=%lu", - static_cast<long unsigned int>(signingSize) - ); - } - else - { - LOGE("## initializePkSigningMemory(): failure - OOM"); - } - - return signingPtr; -} - -JNIEXPORT jlong OLM_PK_SIGNING_FUNC_DEF(createNewPkSigningJni)(JNIEnv *env, jobject thiz) -{ - const char* errorMessage = NULL; - OlmPkSigning *signingPtr = initializePkSigningMemory(); - - // init signing memory allocation - if (!signingPtr) - { - LOGE("## createNewPkSigningJni(): failure - init signing OOM"); - errorMessage = "init signing OOM"; - } - else - { - LOGD("## createNewPkSigningJni(): success - OLM signing created"); - LOGD( - "## createNewPkSigningJni(): signingPtr=%p (jlong)(intptr_t)signingPtr=%lld", - signingPtr, (jlong)(intptr_t)signingPtr - ); - } - - if (errorMessage) - { - // release the allocated data - if (signingPtr) - { - olm_clear_pk_signing(signingPtr); - free(signingPtr); - } - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return (jlong)(intptr_t)signingPtr; -} - -JNIEXPORT void OLM_PK_SIGNING_FUNC_DEF(releasePkSigningJni)(JNIEnv *env, jobject thiz) -{ - LOGD("## releasePkSigningJni(): IN"); - - OlmPkSigning* signingPtr = getPkSigningInstanceId(env, thiz); - - if (!signingPtr) - { - LOGE(" ## releasePkSigningJni(): failure - invalid Signing ptr=NULL"); - } - else - { - LOGD(" ## releasePkSigningJni(): signingPtr=%p", signingPtr); - olm_clear_pk_signing(signingPtr); - - LOGD(" ## releasePkSigningJni(): IN"); - // even if free(NULL) does not crash, logs are performed for debug - // purpose - free(signingPtr); - LOGD(" ## releasePkSigningJni(): OUT"); - } -} - -JNIEXPORT jbyteArray OLM_PK_SIGNING_FUNC_DEF(generateSeedJni)(JNIEnv *env, jobject thiz) -{ - size_t randomLength = olm_pk_signing_seed_length(); - uint8_t *randomBuffPtr = NULL; - jbyteArray randomRet = 0; - const char* errorMessage = NULL; - - if (!setRandomInBuffer(env, &randomBuffPtr, randomLength)) - { - errorMessage = "random buffer init"; - LOGE("## pkSigningGenerateSeedJni(): failure - %s", errorMessage); - } - else if (!(randomRet = env->NewByteArray(randomLength))) - { - errorMessage = "randomRet JNI allocation OOM"; - LOGE(" ## pkSigningGenerateSeedJni(): falure - %s", errorMessage); - } - else - { - env->SetByteArrayRegion( - randomRet, 0, randomLength, (jbyte*)randomBuffPtr - ); - } - - if (randomBuffPtr) - { - memset(randomBuffPtr, 0, randomLength); - free(randomBuffPtr); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return randomRet; -} - -JNIEXPORT jint OLM_PK_SIGNING_FUNC_DEF(seedLength)(JNIEnv *env, jobject thiz) -{ - return (jint) olm_pk_signing_seed_length(); -} - -JNIEXPORT jbyteArray OLM_PK_SIGNING_FUNC_DEF(setKeyFromSeedJni)(JNIEnv *env, jobject thiz, jbyteArray seed) -{ - const char* errorMessage = NULL; - OlmPkSigning *signingPtr = getPkSigningInstanceId(env, thiz); - - jbyteArray publicKeyRet = 0; - jbyte *seedPtr = NULL; - jboolean seedWasCopied = JNI_FALSE; - - if (!signingPtr) - { - errorMessage = "invalid Siging ptr=NULL"; - LOGE(" ## setPkSigningKeyFromSeedJni(): failure - %s", errorMessage); - } - else if (!seed) - { - errorMessage = "invalid seed"; - LOGE(" ## setPkSigningKeyFromSeedJni: failure - %s", errorMessage); - } - else if (!(seedPtr = env->GetByteArrayElements(seed, &seedWasCopied))) - { - errorMessage = "seed JNI allocation OOM"; - LOGE(" ## setPkSigningKeyFromSeedJni(): failure - %s", errorMessage); - } - else - { - size_t publicKeyLength = olm_pk_signing_public_key_length(); - uint8_t *publicKeyPtr = NULL; - size_t seedLength = (size_t)env->GetArrayLength(seed); - if (!(publicKeyPtr = (uint8_t*)malloc(publicKeyLength))) - { - errorMessage = "public key JNI allocation OOM"; - LOGE(" ## setPkSigningKeyFromSeedJni(): falure - %s", errorMessage); - } - else - { - size_t returnValue = olm_pk_signing_key_from_seed( - signingPtr, - publicKeyPtr, publicKeyLength, - seedPtr, seedLength - ); - if (returnValue == olm_error()) - { - errorMessage = olm_pk_signing_last_error(signingPtr); - LOGE(" ## setPkSigningKeyFromSeedJni: failure - olm_pk_signing_key_from_seed Msg=%s", errorMessage); - } - else - { - if (!(publicKeyRet = env->NewByteArray(publicKeyLength))) { - errorMessage = "publicKeyRet JNI allocation OOM"; - LOGE(" ## setPkSigningKeyFromSeedJni(): falure - %s", errorMessage); - } else { - env->SetByteArrayRegion( - publicKeyRet, 0, publicKeyLength, (jbyte*)publicKeyPtr - ); - } - } - } - } - - if (seedPtr) - { - if (seedWasCopied) - { - memset(seedPtr, 0, (size_t)env->GetArrayLength(seed)); - } - env->ReleaseByteArrayElements(seed, seedPtr, JNI_ABORT); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return publicKeyRet; -} - -JNIEXPORT jbyteArray OLM_PK_SIGNING_FUNC_DEF(pkSignJni)(JNIEnv *env, jobject thiz, jbyteArray aMessage) -{ - const char* errorMessage = NULL; - OlmPkSigning *signingPtr = getPkSigningInstanceId(env, thiz); - - jbyteArray signatureRet = 0; - jbyte *messagePtr = NULL; - jboolean messageWasCopied = JNI_FALSE; - - if (!signingPtr) - { - errorMessage = "invalid Siging ptr=NULL"; - LOGE(" ## setPkSignJni(): failure - %s", errorMessage); - } - else if (!aMessage) - { - errorMessage = "message seed"; - LOGE(" ## setPkSignJni: failure - %s", errorMessage); - } - else if (!(messagePtr = env->GetByteArrayElements(aMessage, &messageWasCopied))) - { - errorMessage = "message JNI allocation OOM"; - LOGE(" ## setPkSignJni(): failure - %s", errorMessage); - } - else - { - size_t signatureLength = olm_pk_signature_length(); - uint8_t *signaturePtr = NULL; - size_t messageLength = (size_t)env->GetArrayLength(aMessage); - if (!(signaturePtr = (uint8_t*)malloc(signatureLength))) - { - errorMessage = "signature JNI allocation OOM"; - LOGE(" ## setPkSignJni(): falure - %s", errorMessage); - } - else - { - size_t returnValue = olm_pk_sign( - signingPtr, - (uint8_t *)messagePtr, messageLength, - signaturePtr, signatureLength - ); - if (returnValue == olm_error()) - { - errorMessage = olm_pk_signing_last_error(signingPtr); - LOGE(" ## setPkSignJni: failure - olm_pk_sign Msg=%s", errorMessage); - } - else - { - if (!(signatureRet = env->NewByteArray(signatureLength))) { - errorMessage = "signatureRet JNI allocation OOM"; - LOGE(" ## setPkSignJni(): falure - %s", errorMessage); - } else { - env->SetByteArrayRegion( - signatureRet, 0, signatureLength, (jbyte*)signaturePtr - ); - } - } - } - } - - if (messagePtr) - { - if (messageWasCopied) - { - memset(messagePtr, 0, (size_t)env->GetArrayLength(aMessage)); - } - env->ReleaseByteArrayElements(aMessage, messagePtr, JNI_ABORT); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return signatureRet; -} diff --git a/android/olm-sdk/src/main/jni/olm_pk.h b/android/olm-sdk/src/main/jni/olm_pk.h deleted file mode 100644 index 7a577bb..0000000 --- a/android/olm-sdk/src/main/jni/olm_pk.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 _OLMPK_H -#define _OLMPK_H - -#include "olm_jni.h" -#include "olm/pk.h" - -#define OLM_PK_ENCRYPTION_FUNC_DEF(func_name) FUNC_DEF(OlmPkEncryption,func_name) -#define OLM_PK_DECRYPTION_FUNC_DEF(func_name) FUNC_DEF(OlmPkDecryption,func_name) -#define OLM_PK_SIGNING_FUNC_DEF(func_name) FUNC_DEF(OlmPkSigning,func_name) - -#ifdef __cplusplus -extern "C" { -#endif - -JNIEXPORT jlong OLM_PK_ENCRYPTION_FUNC_DEF(createNewPkEncryptionJni)(JNIEnv *env, jobject thiz); -JNIEXPORT void OLM_PK_ENCRYPTION_FUNC_DEF(releasePkEncryptionJni)(JNIEnv *env, jobject thiz); -JNIEXPORT void OLM_PK_ENCRYPTION_FUNC_DEF(setRecipientKeyJni)(JNIEnv *env, jobject thiz, jbyteArray aKeyBuffer); - -JNIEXPORT jbyteArray OLM_PK_ENCRYPTION_FUNC_DEF(encryptJni)(JNIEnv *env, jobject thiz, jbyteArray aPlaintextBuffer, jobject aEncryptedMsg); - -JNIEXPORT jlong OLM_PK_DECRYPTION_FUNC_DEF(createNewPkDecryptionJni)(JNIEnv *env, jobject thiz); -JNIEXPORT void OLM_PK_DECRYPTION_FUNC_DEF(releasePkDecryptionJni)(JNIEnv *env, jobject thiz); -JNIEXPORT jint OLM_PK_DECRYPTION_FUNC_DEF(privateKeyLength)(JNIEnv *env, jobject thiz); -JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(setPrivateKeyJni)(JNIEnv *env, jobject thiz, jbyteArray key); -JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(generateKeyJni)(JNIEnv *env, jobject thiz); -JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(privateKeyJni)(JNIEnv *env, jobject thiz); -JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(decryptJni)(JNIEnv *env, jobject thiz, jobject aEncryptedMsg); - -JNIEXPORT jlong OLM_PK_SIGNING_FUNC_DEF(createNewPkSigningJni)(JNIEnv *env, jobject thiz); -JNIEXPORT void OLM_PK_SIGNING_FUNC_DEF(releasePkSigningJni)(JNIEnv *env, jobject thiz); -JNIEXPORT jint OLM_PK_SIGNING_FUNC_DEF(seedLength)(JNIEnv *env, jobject thiz); -JNIEXPORT jbyteArray OLM_PK_SIGNING_FUNC_DEF(generateSeedJni)(JNIEnv *env, jobject thiz); -JNIEXPORT jbyteArray OLM_PK_SIGNING_FUNC_DEF(setKeyFromSeedJni)(JNIEnv *env, jobject thiz, jbyteArray seed); -JNIEXPORT jbyteArray OLM_PK_SIGNING_FUNC_DEF(pkSignJni)(JNIEnv *env, jobject thiz, jbyteArray aMessage); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/android/olm-sdk/src/main/jni/olm_sas.cpp b/android/olm-sdk/src/main/jni/olm_sas.cpp deleted file mode 100644 index 400934f..0000000 --- a/android/olm-sdk/src/main/jni/olm_sas.cpp +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Copyright 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. - */ - -#include "olm_sas.h" - -#include "olm/olm.h" - -using namespace AndroidOlmSdk; - -JNIEXPORT jlong OLM_SAS_FUNC_DEF(createNewSASJni)(JNIEnv *env, jobject thiz) -{ - - size_t sasSize = olm_sas_size(); - OlmSAS *sasPtr = (OlmSAS *) malloc(sasSize); - const char* errorMessage = NULL; - - if (!sasPtr) - { - LOGE("## createNewSASJni(): failure - init SAS OOM"); - env->ThrowNew(env->FindClass("java/lang/Exception"), "init sas OOM"); - } - else - { - sasPtr = olm_sas(sasPtr) - LOGD(" ## createNewSASJni(): success - sasPtr=%p (jlong)(intptr_t)accountPtr=%lld",sasPtr,(jlong)(intptr_t)sasPtr); - } - - size_t randomSize = olm_create_sas_random_length(sasPtr); - uint8_t *randomBuffPtr = NULL; - - LOGD("## createNewSASJni(): randomSize=%lu",static_cast<long unsigned int>(randomSize)); - - if ( (0 != randomSize) && !setRandomInBuffer(env, &randomBuffPtr, randomSize)) - { - LOGE("## createNewSASJni(): failure - random buffer init"); - errorMessage = "Failed to init private key"; - } - else - { - size_t result = olm_create_sas(sasPtr, randomBuffPtr, randomSize); - if (result == olm_error()) - { - errorMessage = (const char *)olm_sas_last_error(sasPtr); - LOGE("## createNewSASJni(): failure - error creating SAS Msg=%s", errorMessage); - } - } - - if (randomBuffPtr) - { - memset(randomBuffPtr, 0, randomSize); - free(randomBuffPtr); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return (jlong)(intptr_t)sasPtr; -} - -JNIEXPORT void OLM_SAS_FUNC_DEF(releaseSASJni)(JNIEnv *env, jobject thiz) -{ - LOGD("## releaseSASJni(): IN"); - OlmSAS* sasPtr = getOlmSasInstanceId(env, thiz); - - if (!sasPtr) - { - LOGE("## releaseSessionJni(): failure - invalid Session ptr=NULL"); - } - else - { - olm_clear_sas(sasPtr); - // even if free(NULL) does not crash, logs are performed for debug purpose - free(sasPtr); - } -} - - -JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(getPubKeyJni)(JNIEnv *env, jobject thiz) -{ - LOGD("## getPubKeyJni(): IN"); - const char* errorMessage = NULL; - jbyteArray returnValue = 0; - OlmSAS* sasPtr = getOlmSasInstanceId(env, thiz); - - if (!sasPtr) - { - LOGE("## getPubKeyJni(): failure - invalid SAS ptr=NULL"); - errorMessage = "invalid SAS ptr=NULL"; - } - else - { - size_t pubKeyLength = olm_sas_pubkey_length(sasPtr); - void *pubkey = malloc(pubKeyLength*sizeof(uint8_t)); - size_t result = olm_sas_get_pubkey(sasPtr, pubkey, pubKeyLength); - if (result == olm_error()) - { - errorMessage = (const char *)olm_sas_last_error(sasPtr); - LOGE("## getPubKeyJni(): failure - error getting pub key Msg=%s", errorMessage); - } - else - { - returnValue = env->NewByteArray(pubKeyLength); - env->SetByteArrayRegion(returnValue, 0 , pubKeyLength, (jbyte*)pubkey); - } - if (pubkey) { - free(pubkey); - } - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return returnValue; -} - -JNIEXPORT void OLM_SAS_FUNC_DEF(setTheirPubKey)(JNIEnv *env, jobject thiz,jbyteArray pubKeyBuffer) { - - OlmSAS* sasPtr = getOlmSasInstanceId(env, thiz); - - const char* errorMessage = NULL; - jbyte *pubKeyPtr = NULL; - jboolean pubKeyWasCopied = JNI_FALSE; - - if (!sasPtr) - { - LOGE("## setTheirPubKey(): failure - invalid SAS ptr=NULL"); - errorMessage = "invalid SAS ptr=NULL"; - } else if(!pubKeyBuffer) { - LOGE("## setTheirPubKey(): failure - invalid info"); - errorMessage = "invalid pubKey"; - } - else if (!(pubKeyPtr = env->GetByteArrayElements(pubKeyBuffer, &pubKeyWasCopied))) - { - LOGE(" ## setTheirPubKey(): failure - info JNI allocation OOM"); - errorMessage = "info JNI allocation OOM"; - } - else - { - size_t pubKeyLength = (size_t)env->GetArrayLength(pubKeyBuffer); - size_t result = olm_sas_set_their_key(sasPtr,pubKeyPtr,pubKeyLength); - if (result == olm_error()) - { - errorMessage = (const char *)olm_sas_last_error(sasPtr); - LOGE("## setTheirPubKey(): failure - error setting their key Msg=%s", errorMessage); - } - } - // free alloc - if (pubKeyPtr) - { - if (pubKeyWasCopied) - { - memset(pubKeyPtr, 0, (size_t)env->GetArrayLength(pubKeyBuffer)); - } - env->ReleaseByteArrayElements(pubKeyBuffer, pubKeyPtr, JNI_ABORT); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - -} - -JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(generateShortCodeJni)(JNIEnv *env, jobject thiz, jbyteArray infoStringBytes, jint byteNb) { - LOGD("## generateShortCodeJni(): IN"); - const char* errorMessage = NULL; - jbyteArray returnValue = 0; - OlmSAS* sasPtr = getOlmSasInstanceId(env, thiz); - - jbyte *infoPtr = NULL; - jboolean infoWasCopied = JNI_FALSE; - - if (!sasPtr) - { - LOGE("## generateShortCodeJni(): failure - invalid SAS ptr=NULL"); - errorMessage = "invalid SAS ptr=NULL"; - } else if(!infoStringBytes) { - LOGE("## generateShortCodeJni(): failure - invalid info"); - errorMessage = "invalid info"; - } - else if (!(infoPtr = env->GetByteArrayElements(infoStringBytes, &infoWasCopied))) - { - LOGE(" ## generateShortCodeJni(): failure - info JNI allocation OOM"); - errorMessage = "info JNI allocation OOM"; - } - else { - size_t shortBytesCodeLength = (size_t) byteNb; - void *shortBytesCode = malloc(shortBytesCodeLength * sizeof(uint8_t)); - size_t infoLength = (size_t)env->GetArrayLength(infoStringBytes); - olm_sas_generate_bytes(sasPtr, infoPtr, infoLength, shortBytesCode, shortBytesCodeLength); - returnValue = env->NewByteArray(shortBytesCodeLength); - env->SetByteArrayRegion(returnValue, 0 , shortBytesCodeLength, (jbyte*)shortBytesCode); - free(shortBytesCode); - } - - // free alloc - if (infoPtr) - { - if (infoWasCopied) - { - memset(infoPtr, 0, (size_t)env->GetArrayLength(infoStringBytes)); - } - env->ReleaseByteArrayElements(infoStringBytes, infoPtr, JNI_ABORT); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return returnValue; -} - - -JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(calculateMacJni)(JNIEnv *env, jobject thiz,jbyteArray messageBuffer,jbyteArray infoBuffer) { - LOGD("## calculateMacJni(): 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("## calculateMacJni(): failure - invalid SAS ptr=NULL"); - errorMessage = "invalid SAS ptr=NULL"; - } else if(!messageBuffer) { - LOGE("## calculateMacJni(): failure - invalid message"); - errorMessage = "invalid info"; - } - else if (!(messagePtr = env->GetByteArrayElements(messageBuffer, &messageWasCopied))) - { - LOGE(" ## calculateMacJni(): failure - message JNI allocation OOM"); - errorMessage = "message JNI allocation OOM"; - } - else if (!(infoPtr = env->GetByteArrayElements(infoBuffer, &infoWasCopied))) - { - LOGE(" ## calculateMacJni(): 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(sasPtr,messagePtr,messageLength,infoPtr,infoLength,macPtr,macLength); - if (result == olm_error()) - { - errorMessage = (const char *)olm_sas_last_error(sasPtr); - LOGE("## calculateMacJni(): 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) { - LOGD("## calculateMacLongKdfJni(): 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("## calculateMacLongKdfJni(): failure - invalid SAS ptr=NULL"); - errorMessage = "invalid SAS ptr=NULL"; - } else if(!messageBuffer) { - LOGE("## calculateMacLongKdfJni(): failure - invalid message"); - errorMessage = "invalid info"; - } - else if (!(messagePtr = env->GetByteArrayElements(messageBuffer, &messageWasCopied))) - { - LOGE(" ## calculateMacLongKdfJni(): failure - message JNI allocation OOM"); - errorMessage = "message JNI allocation OOM"; - } - else if (!(infoPtr = env->GetByteArrayElements(infoBuffer, &infoWasCopied))) - { - LOGE(" ## calculateMacLongKdfJni(): 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_long_kdf(sasPtr,messagePtr,messageLength,infoPtr,infoLength,macPtr,macLength); - if (result == olm_error()) - { - errorMessage = (const char *)olm_sas_last_error(sasPtr); - LOGE("## calculateMacLongKdfJni(): 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; -}
\ No newline at end of file diff --git a/android/olm-sdk/src/main/jni/olm_sas.h b/android/olm-sdk/src/main/jni/olm_sas.h deleted file mode 100644 index 3340459..0000000 --- a/android/olm-sdk/src/main/jni/olm_sas.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 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 _OMLSAS_H -#define _OMLSAS_H - -#include "olm_jni.h" -#include "olm/sas.h" - -#define OLM_SAS_FUNC_DEF(func_name) FUNC_DEF(OlmSAS,func_name) - -#ifdef __cplusplus -extern "C" { -#endif - -JNIEXPORT jlong OLM_SAS_FUNC_DEF(createNewSASJni)(JNIEnv *env, jobject thiz); -JNIEXPORT void OLM_SAS_FUNC_DEF(releaseSASJni)(JNIEnv *env, jobject thiz); -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 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(calculateMacLongKdfJni)(JNIEnv *env, jobject thiz, jbyteArray messageBuffer, jbyteArray infoBuffer); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/android/olm-sdk/src/main/jni/olm_session.cpp b/android/olm-sdk/src/main/jni/olm_session.cpp deleted file mode 100644 index 15ad4fe..0000000 --- a/android/olm-sdk/src/main/jni/olm_session.cpp +++ /dev/null @@ -1,977 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016 Vector Creations 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. - */ - -#include "olm_session.h" - -using namespace AndroidOlmSdk; - -/** -* Init memory allocation for a session creation.<br> -* Make sure releaseSessionJni() is called when one is done with the session instance. -* @return valid memory allocation, NULL otherwise -**/ -OlmSession* initializeSessionMemory() -{ - size_t sessionSize = olm_session_size(); - OlmSession* sessionPtr = (OlmSession*)malloc(sessionSize); - - if (sessionPtr) - { - // init session object - sessionPtr = olm_session(sessionPtr); - LOGD("## initializeSessionMemory(): success - OLM session size=%lu",static_cast<long unsigned int>(sessionSize)); - } - else - { - LOGE("## initializeSessionMemory(): failure - OOM"); - } - - return sessionPtr; -} - -JNIEXPORT jlong OLM_SESSION_FUNC_DEF(createNewSessionJni)(JNIEnv *env, jobject thiz) -{ - LOGD("## createNewSessionJni(): IN"); - OlmSession* accountPtr = initializeSessionMemory(); - - if (!accountPtr) - { - LOGE("## initNewAccount(): failure - init session OOM"); - env->ThrowNew(env->FindClass("java/lang/Exception"), "init session OOM"); - } - else - { - LOGD(" ## createNewSessionJni(): success - accountPtr=%p (jlong)(intptr_t)accountPtr=%lld",accountPtr,(jlong)(intptr_t)accountPtr); - } - - return (jlong)(intptr_t)accountPtr; -} - -JNIEXPORT void OLM_SESSION_FUNC_DEF(releaseSessionJni)(JNIEnv *env, jobject thiz) -{ - LOGD("## releaseSessionJni(): IN"); - OlmSession* sessionPtr = getSessionInstanceId(env, thiz); - - if (!sessionPtr) - { - LOGE("## releaseSessionJni(): failure - invalid Session ptr=NULL"); - } - else - { - olm_clear_session(sessionPtr); - - // even if free(NULL) does not crash, logs are performed for debug purpose - free(sessionPtr); - } -} - -// ********************************************************************* -// ********************** OUTBOUND SESSION ***************************** -// ********************************************************************* -/** - * Create a new in-bound session for sending/receiving messages from an - * incoming PRE_KEY message.<br> The recipient is defined as the entity - * with whom the session is established. - * @param aOlmAccountId account instance - * @param aTheirIdentityKey the identity key of the recipient - * @param aTheirOneTimeKey the one time key of the recipient or an exception is thrown - **/ -JNIEXPORT void OLM_SESSION_FUNC_DEF(initOutboundSessionJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aTheirIdentityKeyBuffer, jbyteArray aTheirOneTimeKeyBuffer) -{ - OlmSession* sessionPtr = getSessionInstanceId(env, thiz); - const char* errorMessage = NULL; - OlmAccount* accountPtr = NULL; - - if (!sessionPtr) - { - LOGE("## initOutboundSessionJni(): failure - invalid Session ptr=NULL"); - errorMessage = "invalid Session ptr=NULL"; - } - else if (!(accountPtr = (OlmAccount*)aOlmAccountId)) - { - LOGE("## initOutboundSessionJni(): failure - invalid Account ptr=NULL"); - errorMessage = "invalid Account ptr=NULL"; - } - else if (!aTheirIdentityKeyBuffer || !aTheirOneTimeKeyBuffer) - { - LOGE("## initOutboundSessionJni(): failure - invalid keys"); - errorMessage = "invalid keys"; - } - else - { - size_t randomSize = olm_create_outbound_session_random_length(sessionPtr); - uint8_t *randomBuffPtr = NULL; - - LOGD("## initOutboundSessionJni(): randomSize=%lu",static_cast<long unsigned int>(randomSize)); - - if ( (0 != randomSize) && !setRandomInBuffer(env, &randomBuffPtr, randomSize)) - { - LOGE("## initOutboundSessionJni(): failure - random buffer init"); - errorMessage = "random buffer init"; - } - else - { - jbyte* theirIdentityKeyPtr = NULL; - jbyte* theirOneTimeKeyPtr = NULL; - - // convert identity & one time keys to C strings - if (!(theirIdentityKeyPtr = env->GetByteArrayElements(aTheirIdentityKeyBuffer, 0))) - { - LOGE("## initOutboundSessionJni(): failure - identityKey JNI allocation OOM"); - errorMessage = "identityKey JNI allocation OOM"; - } - else if (!(theirOneTimeKeyPtr = env->GetByteArrayElements(aTheirOneTimeKeyBuffer, 0))) - { - LOGE("## initOutboundSessionJni(): failure - one time Key JNI allocation OOM"); - errorMessage = "one time Key JNI allocation OOM"; - } - else - { - size_t theirIdentityKeyLength = (size_t)env->GetArrayLength(aTheirIdentityKeyBuffer); - size_t theirOneTimeKeyLength = (size_t)env->GetArrayLength(aTheirOneTimeKeyBuffer); - LOGD("## initOutboundSessionJni(): identityKey=%.*s oneTimeKey=%.*s", static_cast<int>(theirIdentityKeyLength), theirIdentityKeyPtr, static_cast<int>(theirOneTimeKeyLength), theirOneTimeKeyPtr); - - size_t sessionResult = olm_create_outbound_session(sessionPtr, - accountPtr, - theirIdentityKeyPtr, - theirIdentityKeyLength, - theirOneTimeKeyPtr, - theirOneTimeKeyLength, - (void*)randomBuffPtr, - randomSize); - if (sessionResult == olm_error()) { - errorMessage = (const char *)olm_session_last_error(sessionPtr); - LOGE("## initOutboundSessionJni(): failure - session creation Msg=%s", errorMessage); - } - else - { - LOGD("## initOutboundSessionJni(): success - result=%lu", static_cast<long unsigned int>(sessionResult)); - } - } - - if (theirIdentityKeyPtr) - { - env->ReleaseByteArrayElements(aTheirIdentityKeyBuffer, theirIdentityKeyPtr, JNI_ABORT); - } - - if (theirOneTimeKeyPtr) - { - env->ReleaseByteArrayElements(aTheirOneTimeKeyBuffer, theirOneTimeKeyPtr, JNI_ABORT); - } - - if (randomBuffPtr) - { - memset(randomBuffPtr, 0, randomSize); - free(randomBuffPtr); - } - } - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } -} - - -// ********************************************************************* -// *********************** INBOUND SESSION ***************************** -// ********************************************************************* -/** - * Create a new in-bound session for sending/receiving messages from an - * incoming PRE_KEY message.<br> - * An exception is thrown if the operation fails. - * @param aOlmAccountId account instance - * @param aOneTimeKeyMsg PRE_KEY message - */ -JNIEXPORT void OLM_SESSION_FUNC_DEF(initInboundSessionJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aOneTimeKeyMsgBuffer) -{ - const char* errorMessage = NULL; - OlmSession *sessionPtr = getSessionInstanceId(env,thiz); - OlmAccount *accountPtr = NULL; - size_t sessionResult; - - if (!sessionPtr) - { - LOGE("## initInboundSessionJni(): failure - invalid Session ptr=NULL"); - errorMessage = "invalid Session ptr=NULL"; - } - else if (!(accountPtr = (OlmAccount*)aOlmAccountId)) - { - LOGE("## initInboundSessionJni(): failure - invalid Account ptr=NULL"); - errorMessage = "invalid Account ptr=NULL"; - } - else if (!aOneTimeKeyMsgBuffer) - { - LOGE("## initInboundSessionJni(): failure - invalid message"); - errorMessage = "invalid message"; - } - else - { - jbyte* messagePtr = env->GetByteArrayElements(aOneTimeKeyMsgBuffer, 0); - - if (!messagePtr) - { - LOGE("## initInboundSessionJni(): failure - message JNI allocation OOM"); - errorMessage = "message JNI allocation OOM"; - } - else - { - size_t messageLength = (size_t)env->GetArrayLength(aOneTimeKeyMsgBuffer); - LOGD("## initInboundSessionJni(): messageLength=%lu message=%.*s", static_cast<long unsigned int>(messageLength), static_cast<int>(messageLength), messagePtr); - - sessionResult = olm_create_inbound_session(sessionPtr, accountPtr, (void*)messagePtr , messageLength); - - if (sessionResult == olm_error()) - { - errorMessage = olm_session_last_error(sessionPtr); - LOGE("## initInboundSessionJni(): failure - init inbound session creation Msg=%s", errorMessage); - } - else - { - LOGD("## initInboundSessionJni(): success - result=%lu", static_cast<long unsigned int>(sessionResult)); - } - - // free local alloc - env->ReleaseByteArrayElements(aOneTimeKeyMsgBuffer, messagePtr, JNI_ABORT); - } - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } -} - -/** - * Create a new in-bound session for sending/receiving messages from an - * incoming PRE_KEY message based on the recipient identity key.<br> - * An exception is thrown if the operation fails. - * @param aOlmAccountId account instance - * @param aTheirIdentityKey the identity key of the recipient - * @param aOneTimeKeyMsg encrypted message - */ -JNIEXPORT void OLM_SESSION_FUNC_DEF(initInboundSessionFromIdKeyJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aTheirIdentityKeyBuffer, jbyteArray aOneTimeKeyMsgBuffer) -{ - const char* errorMessage = NULL; - - OlmSession *sessionPtr = getSessionInstanceId(env, thiz); - OlmAccount *accountPtr = NULL; - jbyte *messagePtr = NULL; - jbyte *theirIdentityKeyPtr = NULL; - size_t sessionResult; - - if (!sessionPtr) - { - LOGE("## initInboundSessionFromIdKeyJni(): failure - invalid Session ptr=NULL"); - errorMessage = "invalid Session ptr=NULL"; - } - else if (!(accountPtr = (OlmAccount*)aOlmAccountId)) - { - LOGE("## initInboundSessionFromIdKeyJni(): failure - invalid Account ptr=NULL"); - errorMessage = "invalid Account ptr=NULL"; - } - else if (!aTheirIdentityKeyBuffer) - { - LOGE("## initInboundSessionFromIdKeyJni(): failure - invalid theirIdentityKey"); - errorMessage = "invalid theirIdentityKey"; - } - else if (!aOneTimeKeyMsgBuffer) - { - LOGE("## initInboundSessionJni(): failure - invalid one time key message"); - errorMessage = "invalid invalid one time key message"; - } - else if (!(messagePtr = env->GetByteArrayElements(aOneTimeKeyMsgBuffer, 0))) - { - LOGE("## initInboundSessionFromIdKeyJni(): failure - message JNI allocation OOM"); - errorMessage = "message JNI allocation OOM"; - } - else if(!(theirIdentityKeyPtr = env->GetByteArrayElements(aTheirIdentityKeyBuffer, 0))) - { - LOGE("## initInboundSessionFromIdKeyJni(): failure - theirIdentityKey JNI allocation OOM"); - errorMessage = "theirIdentityKey JNI allocation OOM"; - } - else - { - size_t messageLength = (size_t)env->GetArrayLength(aOneTimeKeyMsgBuffer); - size_t theirIdentityKeyLength = (size_t)env->GetArrayLength(aTheirIdentityKeyBuffer); - - LOGD("## initInboundSessionFromIdKeyJni(): message=%.*s messageLength=%lu", static_cast<int>(messageLength), messagePtr, static_cast<long unsigned int>(messageLength)); - - sessionResult = olm_create_inbound_session_from(sessionPtr, accountPtr, theirIdentityKeyPtr, theirIdentityKeyLength, (void*)messagePtr , messageLength); - if (sessionResult == olm_error()) - { - errorMessage = (const char *)olm_session_last_error(sessionPtr); - LOGE("## initInboundSessionFromIdKeyJni(): failure - init inbound session creation Msg=%s", errorMessage); - } - else - { - LOGD("## initInboundSessionFromIdKeyJni(): success - result=%lu", static_cast<long unsigned int>(sessionResult)); - } - } - - // free local alloc - if (messagePtr) - { - env->ReleaseByteArrayElements(aOneTimeKeyMsgBuffer, messagePtr, JNI_ABORT); - } - - if (theirIdentityKeyPtr) - { - env->ReleaseByteArrayElements(aTheirIdentityKeyBuffer, theirIdentityKeyPtr, JNI_ABORT); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } -} - -/** - * Checks if the 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). - * @param aOneTimeKeyMsg PRE KEY message - * @return true if the PRE_KEY message matches - */ -JNIEXPORT jboolean OLM_SESSION_FUNC_DEF(matchesInboundSessionJni)(JNIEnv *env, jobject thiz, jbyteArray aOneTimeKeyMsgBuffer) -{ - jboolean retCode = JNI_FALSE; - OlmSession *sessionPtr = getSessionInstanceId(env, thiz); - jbyte *messagePtr = NULL; - - if (!sessionPtr) - { - LOGE("## matchesInboundSessionJni(): failure - invalid Session ptr=NULL"); - } - else if (!aOneTimeKeyMsgBuffer) - { - LOGE("## matchesInboundSessionJni(): failure - invalid one time key message"); - } - else if (!(messagePtr = env->GetByteArrayElements(aOneTimeKeyMsgBuffer, 0))) - { - LOGE("## matchesInboundSessionJni(): failure - one time key JNI allocation OOM"); - } - else - { - size_t messageLength = (size_t)env->GetArrayLength(aOneTimeKeyMsgBuffer); - - size_t matchResult = olm_matches_inbound_session(sessionPtr, (void*)messagePtr , messageLength); - //if(matchResult == olm_error()) { - // for now olm_matches_inbound_session() returns 1 when it succeeds, otherwise 1- or 0 - if (matchResult != 1) { - LOGE("## matchesInboundSessionJni(): failure - no match Msg=%s",(const char *)olm_session_last_error(sessionPtr)); - } - else - { - retCode = JNI_TRUE; - LOGD("## matchesInboundSessionJni(): success - result=%lu", static_cast<long unsigned int>(matchResult)); - } - } - - // free local alloc - if (messagePtr) - { - env->ReleaseByteArrayElements(aOneTimeKeyMsgBuffer, messagePtr, JNI_ABORT); - } - - return retCode; -} - -/** - * Checks if the PRE_KEY message is for this in-bound session based on the sender identity key.<br> - * This API may be used to process a "m.room.encrypted" event when type = 1 (PRE_KEY). - * @param aTheirIdentityKey the identity key of the sender - * @param aOneTimeKeyMsg PRE KEY message - * @return true if the PRE_KEY message matches. - */ -JNIEXPORT jboolean JNICALL OLM_SESSION_FUNC_DEF(matchesInboundSessionFromIdKeyJni)(JNIEnv *env, jobject thiz, jbyteArray aTheirIdentityKeyBuffer, jbyteArray aOneTimeKeyMsgBuffer) -{ - jboolean retCode = JNI_FALSE; - OlmSession *sessionPtr = getSessionInstanceId(env, thiz); - jbyte *messagePtr = NULL; - jbyte *theirIdentityKeyPtr = NULL; - - if (!sessionPtr) - { - LOGE("## matchesInboundSessionFromIdKeyJni(): failure - invalid Session ptr=NULL"); - } - else if (!aTheirIdentityKeyBuffer) - { - LOGE("## matchesInboundSessionFromIdKeyJni(): failure - invalid theirIdentityKey"); - } - else if (!(theirIdentityKeyPtr = env->GetByteArrayElements(aTheirIdentityKeyBuffer, 0))) - { - LOGE("## matchesInboundSessionFromIdKeyJni(): failure - theirIdentityKey JNI allocation OOM"); - } - else if (!aOneTimeKeyMsgBuffer) - { - LOGE("## matchesInboundSessionFromIdKeyJni(): failure - invalid one time key message"); - } - else if (!(messagePtr = env->GetByteArrayElements(aOneTimeKeyMsgBuffer, 0))) - { - LOGE("## matchesInboundSessionFromIdKeyJni(): failure - one time key JNI allocation OOM"); - } - else - { - size_t identityKeyLength = (size_t)env->GetArrayLength(aTheirIdentityKeyBuffer); - size_t messageLength = (size_t)env->GetArrayLength(aOneTimeKeyMsgBuffer); - size_t matchResult = olm_matches_inbound_session_from(sessionPtr, (void const *)theirIdentityKeyPtr, identityKeyLength, (void*)messagePtr , messageLength); - - //if(matchResult == olm_error()) { - // for now olm_matches_inbound_session() returns 1 when it succeeds, otherwise 1- or 0 - if (matchResult != 1) - { - LOGE("## matchesInboundSessionFromIdKeyJni(): failure - no match Msg=%s",(const char *)olm_session_last_error(sessionPtr)); - } - else - { - retCode = JNI_TRUE; - LOGD("## matchesInboundSessionFromIdKeyJni(): success - result=%lu", static_cast<long unsigned int>(matchResult)); - } - } - - // free local alloc - if (theirIdentityKeyPtr) - { - env->ReleaseByteArrayElements(aTheirIdentityKeyBuffer, theirIdentityKeyPtr, JNI_ABORT); - } - - if (messagePtr) - { - env->ReleaseByteArrayElements(aOneTimeKeyMsgBuffer, messagePtr, JNI_ABORT); - } - - return retCode; -} - -/** - * Encrypt a message using the session.<br> - * An exception is thrown if the operation fails. - * @param aClearMsg clear text message - * @param [out] aEncryptedMsg ciphered message - * @return the encrypted message - */ -JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aClearMsgBuffer, jobject aEncryptedMsg) -{ - jbyteArray encryptedMsgRet = 0; - const char* errorMessage = NULL; - - OlmSession *sessionPtr = getSessionInstanceId(env, thiz); - jbyte *clearMsgPtr = NULL; - jboolean clearMsgIsCopied = JNI_FALSE; - jclass encryptedMsgJClass = 0; - jfieldID typeMsgFieldId; - - LOGD("## encryptMessageJni(): IN "); - - if (!sessionPtr) - { - LOGE("## encryptMessageJni(): failure - invalid Session ptr=NULL"); - errorMessage = "invalid Session ptr=NULL"; - } - else if (!aClearMsgBuffer) - { - LOGE("## encryptMessageJni(): failure - invalid clear message"); - errorMessage = "invalid clear message"; - } - else if (!aEncryptedMsg) - { - LOGE("## encryptMessageJni(): failure - invalid encrypted message"); - errorMessage = "invalid encrypted message"; - } - else if (!(clearMsgPtr = env->GetByteArrayElements(aClearMsgBuffer, &clearMsgIsCopied))) - { - LOGE("## encryptMessageJni(): failure - clear message JNI allocation OOM"); - errorMessage = "clear message JNI allocation OOM"; - } - else if (!(encryptedMsgJClass = env->GetObjectClass(aEncryptedMsg))) - { - LOGE("## encryptMessageJni(): failure - unable to get crypted message class"); - errorMessage = "unable to get crypted message class"; - } - else if (!(typeMsgFieldId = env->GetFieldID(encryptedMsgJClass,"mType","J"))) - { - LOGE("## encryptMessageJni(): failure - unable to get message type field"); - errorMessage = "unable to get message type field"; - } - else - { - // get message type - size_t messageType = olm_encrypt_message_type(sessionPtr); - uint8_t *randomBuffPtr = NULL; - - // compute random buffer - // Note: olm_encrypt_random_length() can return 0, which means - // it just does not need new random data to encrypt a new message - size_t randomLength = olm_encrypt_random_length(sessionPtr); - - LOGD("## encryptMessageJni(): randomLength=%lu", static_cast<long unsigned int>(randomLength)); - - if ((0 != randomLength) && !setRandomInBuffer(env, &randomBuffPtr, randomLength)) - { - LOGE("## encryptMessageJni(): failure - random buffer init"); - errorMessage = "random buffer init"; - } - else - { - // alloc buffer for encrypted message - size_t clearMsgLength = (size_t)env->GetArrayLength(aClearMsgBuffer); - size_t encryptedMsgLength = olm_encrypt_message_length(sessionPtr, clearMsgLength); - - void *encryptedMsgPtr = malloc(encryptedMsgLength*sizeof(uint8_t)); - - if (!encryptedMsgPtr) - { - LOGE("## encryptMessageJni(): failure - encryptedMsgPtr buffer OOM"); - errorMessage = "encryptedMsgPtr buffer OOM"; - } - else - { - if (0 == randomLength) - { - LOGW("## encryptMessageJni(): random buffer is not required"); - } - - LOGD("## encryptMessageJni(): messageType=%lu randomLength=%lu clearMsgLength=%lu encryptedMsgLength=%lu",static_cast<long unsigned int>(messageType),static_cast<long unsigned int>(randomLength), static_cast<long unsigned int>(clearMsgLength), static_cast<long unsigned int>(encryptedMsgLength)); - // encrypt message - size_t result = olm_encrypt(sessionPtr, - (void const *)clearMsgPtr, - clearMsgLength, - randomBuffPtr, - randomLength, - encryptedMsgPtr, - encryptedMsgLength); - if (result == olm_error()) - { - errorMessage = (const char *)olm_session_last_error(sessionPtr); - LOGE("## encryptMessageJni(): failure - Msg=%s", errorMessage); - } - else - { - // update message type: PRE KEY or normal - env->SetLongField(aEncryptedMsg, typeMsgFieldId, (jlong)messageType); - - encryptedMsgRet = env->NewByteArray(encryptedMsgLength); - env->SetByteArrayRegion(encryptedMsgRet, 0 , encryptedMsgLength, (jbyte*)encryptedMsgPtr); - - LOGD("## encryptMessageJni(): success - result=%lu Type=%lu encryptedMsg=%.*s", static_cast<long unsigned int>(result), static_cast<unsigned long int>(messageType), static_cast<int>(result), (const char*)encryptedMsgPtr); - } - - free(encryptedMsgPtr); - } - - memset(randomBuffPtr, 0, randomLength); - free(randomBuffPtr); - } - } - - // free alloc - if (clearMsgPtr) - { - if (clearMsgIsCopied) - { - memset(clearMsgPtr, 0, (size_t)env->GetArrayLength(aClearMsgBuffer)); - } - env->ReleaseByteArrayElements(aClearMsgBuffer, clearMsgPtr, JNI_ABORT); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return encryptedMsgRet; -} - -/** - * Decrypt a message using the session.<br> - * An exception is thrown if the operation fails. - * @param aEncryptedMsg message to decrypt - * @return decrypted message if operation succeed - */ -JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jobject aEncryptedMsg) -{ - const char* errorMessage = NULL; - - jbyteArray decryptedMsgRet = 0; - - jclass encryptedMsgJClass = 0; - jstring encryptedMsgJstring = 0; // <= obtained from encryptedMsgFieldId - // field IDs - jfieldID encryptedMsgFieldId; - jfieldID typeMsgFieldId; - // ptrs - OlmSession *sessionPtr = getSessionInstanceId(env, thiz); - const char *encryptedMsgPtr = NULL; // <= obtained from encryptedMsgJstring - uint8_t *plainTextMsgPtr = NULL; - char *tempEncryptedPtr = NULL; - - LOGD("## decryptMessageJni(): IN - OlmSession"); - - if (!sessionPtr) - { - LOGE("## decryptMessageJni(): failure - invalid Session ptr=NULL"); - errorMessage = "invalid Session ptr=NULL"; - } - else if (!aEncryptedMsg) - { - LOGE("## decryptMessageJni(): failure - invalid encrypted message"); - errorMessage = "invalid encrypted message"; - } - else if (!(encryptedMsgJClass = env->GetObjectClass(aEncryptedMsg))) - { - LOGE("## decryptMessageJni(): failure - unable to get encrypted message class"); - errorMessage = "unable to get encrypted message class"; - } - else if (!(encryptedMsgFieldId = env->GetFieldID(encryptedMsgJClass,"mCipherText","Ljava/lang/String;"))) - { - LOGE("## decryptMessageJni(): failure - unable to get message field"); - errorMessage = "unable to get message field"; - } - else if (!(typeMsgFieldId = env->GetFieldID(encryptedMsgJClass,"mType","J"))) - { - LOGE("## decryptMessageJni(): failure - unable to get message type field"); - errorMessage = "unable to get message type field"; - } - else if (!(encryptedMsgJstring = (jstring)env->GetObjectField(aEncryptedMsg, encryptedMsgFieldId))) - { - LOGE("## decryptMessageJni(): failure - JNI encrypted object "); - errorMessage = "JNI encrypted object"; - } - else if (!(encryptedMsgPtr = env->GetStringUTFChars(encryptedMsgJstring, 0))) - { - LOGE("## decryptMessageJni(): failure - encrypted message JNI allocation OOM"); - errorMessage = "encrypted message JNI allocation OOM"; - } - else - { - // get message type - size_t encryptedMsgType = (size_t)env->GetLongField(aEncryptedMsg, typeMsgFieldId); - // get encrypted message length - size_t encryptedMsgLength = (size_t)env->GetStringUTFLength(encryptedMsgJstring); - - // create a dedicated temp buffer to be used in next Olm API calls - tempEncryptedPtr = static_cast<char*>(malloc(encryptedMsgLength*sizeof(uint8_t))); - memcpy(tempEncryptedPtr, encryptedMsgPtr, encryptedMsgLength); - LOGD("## decryptMessageJni(): MsgType=%lu encryptedMsgLength=%lu encryptedMsg=%.*s",static_cast<long unsigned int>(encryptedMsgType),static_cast<long unsigned int>(encryptedMsgLength), static_cast<int>(encryptedMsgLength), encryptedMsgPtr); - - // get max plaintext length - size_t maxPlainTextLength = olm_decrypt_max_plaintext_length(sessionPtr, - static_cast<size_t>(encryptedMsgType), - static_cast<void*>(tempEncryptedPtr), - encryptedMsgLength); - // Note: tempEncryptedPtr is destroyed by olm_decrypt_max_plaintext_length() - - if (maxPlainTextLength == olm_error()) - { - errorMessage = (const char *)olm_session_last_error(sessionPtr); - LOGE("## decryptMessageJni(): failure - olm_decrypt_max_plaintext_length Msg=%s", errorMessage); - } - else - { - LOGD("## decryptMessageJni(): maxPlaintextLength=%lu",static_cast<long unsigned int>(maxPlainTextLength)); - - // allocate output decrypted message - plainTextMsgPtr = static_cast<uint8_t*>(malloc(maxPlainTextLength*sizeof(uint8_t))); - - // decrypt, but before reload encrypted buffer (previous one was destroyed) - memcpy(tempEncryptedPtr, encryptedMsgPtr, encryptedMsgLength); - size_t plaintextLength = olm_decrypt(sessionPtr, - encryptedMsgType, - (void*)tempEncryptedPtr, - encryptedMsgLength, - plainTextMsgPtr, - maxPlainTextLength); - if (plaintextLength == olm_error()) - { - errorMessage = (const char *)olm_session_last_error(sessionPtr); - LOGE("## decryptMessageJni(): failure - olm_decrypt Msg=%s", errorMessage); - } - else - { - decryptedMsgRet = env->NewByteArray(plaintextLength); - env->SetByteArrayRegion(decryptedMsgRet, 0 , plaintextLength, (jbyte*)plainTextMsgPtr); - - LOGD(" ## decryptMessageJni(): UTF-8 Conversion - decrypted returnedLg=%lu OK",static_cast<long unsigned int>(plaintextLength)); - } - - memset(plainTextMsgPtr, 0, maxPlainTextLength); - } - } - - // free alloc - if (encryptedMsgPtr) - { - env->ReleaseStringUTFChars(encryptedMsgJstring, encryptedMsgPtr); - } - - if (tempEncryptedPtr) - { - free(tempEncryptedPtr); - } - - if (plainTextMsgPtr) - { - free(plainTextMsgPtr); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return decryptedMsgRet; -} - -/** - * Get the session identifier for this session. - * An exception is thrown if the operation fails. - * @return the session identifier - */ -JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(getSessionIdentifierJni)(JNIEnv *env, jobject thiz) -{ - const char* errorMessage = NULL; - jbyteArray returnValue = 0; - - LOGD("## getSessionIdentifierJni(): IN "); - - OlmSession *sessionPtr = getSessionInstanceId(env, thiz); - - if (!sessionPtr) - { - LOGE("## getSessionIdentifierJni(): failure - invalid Session ptr=NULL"); - errorMessage = "invalid Session ptr=NULL"; - } - else - { - // get the size to alloc to contain the id - size_t lengthSessionId = olm_session_id_length(sessionPtr); - LOGD("## getSessionIdentifierJni(): lengthSessionId=%lu",static_cast<long unsigned int>(lengthSessionId)); - - void *sessionIdPtr = malloc(lengthSessionId*sizeof(uint8_t)); - - if (!sessionIdPtr) - { - LOGE("## getSessionIdentifierJni(): failure - identifier allocation OOM"); - errorMessage = "identifier allocation OOM"; - } - else - { - size_t result = olm_session_id(sessionPtr, sessionIdPtr, lengthSessionId); - - if (result == olm_error()) - { - errorMessage = (const char *)olm_session_last_error(sessionPtr); - LOGE("## getSessionIdentifierJni(): failure - get session identifier failure Msg=%s", errorMessage); - } - else - { - LOGD("## getSessionIdentifierJni(): success - result=%lu sessionId=%.*s",static_cast<long unsigned int>(result), static_cast<int>(result), (char*)sessionIdPtr); - - returnValue = env->NewByteArray(result); - env->SetByteArrayRegion(returnValue, 0 , result, (jbyte*)sessionIdPtr); - } - - free(sessionIdPtr); - } - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return returnValue; -} - -/** - * Serialize and encrypt session instance.<br> - * An exception is thrown if the operation fails. - * @param aKeyBuffer key used to encrypt the serialized account data - * @return the serialised account as bytes buffer. - **/ -JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKeyBuffer) -{ - const char* errorMessage = NULL; - jbyteArray returnValue = 0; - - jbyte* keyPtr = NULL; - jboolean keyWasCopied = JNI_FALSE; - OlmSession* sessionPtr = getSessionInstanceId(env, thiz); - - LOGD("## serializeJni(): IN"); - - if (!sessionPtr) - { - LOGE(" ## serializeJni(): failure - invalid session ptr"); - errorMessage = "invalid session ptr"; - } - else if (!aKeyBuffer) - { - LOGE(" ## serializeJni(): failure - invalid key"); - errorMessage = "invalid key"; - } - else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, &keyWasCopied))) - { - LOGE(" ## serializeJni(): failure - keyPtr JNI allocation OOM"); - errorMessage = "ikeyPtr JNI allocation OOM"; - } - else - { - size_t pickledLength = olm_pickle_session_length(sessionPtr); - size_t keyLength = (size_t)env->GetArrayLength(aKeyBuffer); - LOGD(" ## serializeJni(): pickledLength=%lu keyLength=%lu",static_cast<long unsigned int>(pickledLength), static_cast<long unsigned int>(keyLength)); - - void *pickledPtr = malloc(pickledLength*sizeof(uint8_t)); - - if (!pickledPtr) - { - LOGE(" ## serializeJni(): failure - pickledPtr buffer OOM"); - errorMessage = "pickledPtr buffer OOM"; - } - else - { - size_t result = olm_pickle_session(sessionPtr, - (void const *)keyPtr, - keyLength, - (void*)pickledPtr, - pickledLength); - if (result == olm_error()) - { - errorMessage = olm_session_last_error(sessionPtr); - LOGE(" ## serializeJni(): failure - olm_pickle_session() Msg=%s", errorMessage); - } - else - { - LOGD(" ## serializeJni(): success - result=%lu pickled=%.*s", static_cast<long unsigned int>(result), static_cast<int>(pickledLength), static_cast<char*>(pickledPtr)); - - returnValue = env->NewByteArray(pickledLength); - env->SetByteArrayRegion(returnValue, 0 , pickledLength, (jbyte*)pickledPtr); - } - - free(pickledPtr); - } - } - - // free alloc - if (keyPtr) - { - if (keyWasCopied) { - memset(keyPtr, 0, (size_t)env->GetArrayLength(aKeyBuffer)); - } - env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT); - } - - if (errorMessage) - { - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return returnValue; -} - -/** - * Allocate a new session and initialize it with the serialisation data.<br> - * An exception is thrown if the operation fails. - * @param aSerializedData the session serialisation buffer - * @param aKey the key used to encrypt the serialized account data - * @return the deserialized session - **/ -JNIEXPORT jlong OLM_SESSION_FUNC_DEF(deserializeJni)(JNIEnv *env, jobject thiz, jbyteArray aSerializedDataBuffer, jbyteArray aKeyBuffer) -{ - const char* errorMessage = NULL; - OlmSession* sessionPtr = initializeSessionMemory(); - jbyte* keyPtr = NULL; - jboolean keyWasCopied = JNI_FALSE; - jbyte* pickledPtr = NULL; - - LOGD("## deserializeJni(): IN"); - - if (!sessionPtr) - { - LOGE(" ## deserializeJni(): failure - session failure OOM"); - errorMessage = "session failure OOM"; - } - else if (!aKeyBuffer) - { - LOGE(" ## deserializeJni(): failure - invalid key"); - errorMessage = "invalid key"; - } - else if (!aSerializedDataBuffer) - { - LOGE(" ## deserializeJni(): failure - serialized data"); - errorMessage = "serialized data"; - } - else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, &keyWasCopied))) - { - LOGE(" ## deserializeJni(): failure - keyPtr JNI allocation OOM"); - errorMessage = "keyPtr JNI allocation OOM"; - } - else if (!(pickledPtr = env->GetByteArrayElements(aSerializedDataBuffer, 0))) - { - LOGE(" ## deserializeJni(): failure - pickledPtr JNI allocation OOM"); - errorMessage = "pickledPtr JNI allocation OOM"; - } - else - { - size_t pickledLength = (size_t)env->GetArrayLength(aSerializedDataBuffer); - size_t keyLength = (size_t)env->GetArrayLength(aKeyBuffer); - LOGD(" ## deserializeJni(): pickledLength=%lu keyLength=%lu",static_cast<long unsigned int>(pickledLength), static_cast<long unsigned int>(keyLength)); - LOGD(" ## deserializeJni(): pickled=%.*s",static_cast<int>(pickledLength), (char const *)pickledPtr); - - size_t result = olm_unpickle_session(sessionPtr, - (void const *)keyPtr, - keyLength, - (void*)pickledPtr, - pickledLength); - if (result == olm_error()) - { - errorMessage = olm_session_last_error(sessionPtr); - LOGE(" ## deserializeJni(): failure - olm_unpickle_account() Msg=%s", errorMessage); - } - else - { - LOGD(" ## initJni(): success - result=%lu ", static_cast<long unsigned int>(result)); - } - } - - // free alloc - if (keyPtr) - { - if (keyWasCopied) { - memset(keyPtr, 0, (size_t)env->GetArrayLength(aKeyBuffer)); - } - env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT); - } - - if (pickledPtr) - { - env->ReleaseByteArrayElements(aSerializedDataBuffer, pickledPtr, JNI_ABORT); - } - - if (errorMessage) - { - if (sessionPtr) - { - olm_clear_session(sessionPtr); - free(sessionPtr); - } - env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); - } - - return (jlong)(intptr_t)sessionPtr; -} diff --git a/android/olm-sdk/src/main/jni/olm_session.h b/android/olm-sdk/src/main/jni/olm_session.h deleted file mode 100644 index 534e830..0000000 --- a/android/olm-sdk/src/main/jni/olm_session.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016 Vector Creations 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 _OLMSESSION_H -#define _OLMSESSION_H - -#include "olm_jni.h" -#include "olm/olm.h" - -#define OLM_SESSION_FUNC_DEF(func_name) FUNC_DEF(OlmSession,func_name) - -#ifdef __cplusplus -extern "C" { -#endif - -// session creation/destruction -JNIEXPORT void OLM_SESSION_FUNC_DEF(releaseSessionJni)(JNIEnv *env, jobject thiz); -JNIEXPORT jlong OLM_SESSION_FUNC_DEF(createNewSessionJni)(JNIEnv *env, jobject thiz); - -// outbound session -JNIEXPORT void OLM_SESSION_FUNC_DEF(initOutboundSessionJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aTheirIdentityKey, jbyteArray aTheirOneTimeKey); - -// inbound sessions: establishment based on PRE KEY message -JNIEXPORT void OLM_SESSION_FUNC_DEF(initInboundSessionJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aOneTimeKeyMsg); -JNIEXPORT void OLM_SESSION_FUNC_DEF(initInboundSessionFromIdKeyJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aTheirIdentityKey, jbyteArray aOneTimeKeyMsg); - -// match inbound sessions: based on PRE KEY message -JNIEXPORT jboolean OLM_SESSION_FUNC_DEF(matchesInboundSessionJni)(JNIEnv *env, jobject thiz, jbyteArray aOneTimeKeyMsg); -JNIEXPORT jboolean OLM_SESSION_FUNC_DEF(matchesInboundSessionFromIdKeyJni)(JNIEnv *env, jobject thiz, jbyteArray aTheirIdentityKey, jbyteArray aOneTimeKeyMsg); - -// encrypt/decrypt -JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aClearMsg, 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); - -// serialization -JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKey); -JNIEXPORT jlong OLM_SESSION_FUNC_DEF(deserializeJni)(JNIEnv *env, jobject thiz, jbyteArray aSerializedData, jbyteArray aKey); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/android/olm-sdk/src/main/jni/olm_utility.cpp b/android/olm-sdk/src/main/jni/olm_utility.cpp deleted file mode 100644 index da27eda..0000000 --- a/android/olm-sdk/src/main/jni/olm_utility.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016 Vector Creations 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. - */ - -#include "olm_utility.h" - -using namespace AndroidOlmSdk; - -OlmUtility* initializeUtilityMemory() -{ - size_t utilitySize = olm_utility_size(); - OlmUtility* utilityPtr = (OlmUtility*)malloc(utilitySize); - - if (utilityPtr) - { - utilityPtr = olm_utility(utilityPtr); - LOGD("## initializeUtilityMemory(): success - OLM utility size=%lu",static_cast<long unsigned int>(utilitySize)); - } - else - { - LOGE("## initializeUtilityMemory(): failure - OOM"); - } - - return utilityPtr; -} - -JNIEXPORT jlong OLM_UTILITY_FUNC_DEF(createUtilityJni)(JNIEnv *env, jobject thiz) -{ - OlmUtility* utilityPtr = initializeUtilityMemory(); - - LOGD("## createUtilityJni(): IN"); - - // init account memory allocation - if (!utilityPtr) - { - LOGE(" ## createUtilityJni(): failure - init OOM"); - env->ThrowNew(env->FindClass("java/lang/Exception"), "init OOM"); - } - else - { - LOGD(" ## createUtilityJni(): success"); - } - - return (jlong)(intptr_t)utilityPtr; -} - - -JNIEXPORT void OLM_UTILITY_FUNC_DEF(releaseUtilityJni)(JNIEnv *env, jobject thiz) -{ - OlmUtility* utilityPtr = getUtilityInstanceId(env, thiz); - - LOGD("## releaseUtilityJni(): IN"); - - if (!utilityPtr) - { - LOGE("## releaseUtilityJni(): failure - utility ptr=NULL"); - } - else - { - olm_clear_utility(utilityPtr); - free(utilityPtr); - } -} - - -/** - * Verify an ed25519 signature. - * @param aSignature the base64-encoded message signature to be checked. - * @param aKey the ed25519 key (fingerprint key) - * @param aMessage the message which was signed - * @return 0 if validation succeed, an error message string if operation failed - */ -JNIEXPORT jstring OLM_UTILITY_FUNC_DEF(verifyEd25519SignatureJni)(JNIEnv *env, jobject thiz, jbyteArray aSignatureBuffer, jbyteArray aKeyBuffer, jbyteArray aMessageBuffer) -{ - jstring errorMessageRetValue = 0; - OlmUtility* utilityPtr = getUtilityInstanceId(env, thiz); - jbyte* signaturePtr = NULL; - jbyte* keyPtr = NULL; - jbyte* messagePtr = NULL; - jboolean messageWasCopied = JNI_FALSE; - - LOGD("## verifyEd25519SignatureJni(): IN"); - - if (!utilityPtr) - { - LOGE(" ## verifyEd25519SignatureJni(): failure - invalid utility ptr=NULL"); - } - else if (!aSignatureBuffer || !aKeyBuffer || !aMessageBuffer) - { - LOGE(" ## verifyEd25519SignatureJni(): failure - invalid input parameters "); - } - else if (!(signaturePtr = env->GetByteArrayElements(aSignatureBuffer, 0))) - { - LOGE(" ## verifyEd25519SignatureJni(): failure - signature JNI allocation OOM"); - } - else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, 0))) - { - LOGE(" ## verifyEd25519SignatureJni(): failure - key JNI allocation OOM"); - } - else if (!(messagePtr = env->GetByteArrayElements(aMessageBuffer, &messageWasCopied))) - { - LOGE(" ## verifyEd25519SignatureJni(): failure - message JNI allocation OOM"); - } - else - { - size_t signatureLength = (size_t)env->GetArrayLength(aSignatureBuffer); - size_t keyLength = (size_t)env->GetArrayLength(aKeyBuffer); - size_t messageLength = (size_t)env->GetArrayLength(aMessageBuffer); - LOGD(" ## verifyEd25519SignatureJni(): signatureLength=%lu keyLength=%lu messageLength=%lu",static_cast<long unsigned int>(signatureLength),static_cast<long unsigned int>(keyLength),static_cast<long unsigned int>(messageLength)); - LOGD(" ## verifyEd25519SignatureJni(): key=%.*s", static_cast<int>(keyLength), keyPtr); - - size_t result = olm_ed25519_verify(utilityPtr, - (void const *)keyPtr, - keyLength, - (void const *)messagePtr, - messageLength, - (void*)signaturePtr, - signatureLength); - if (result == olm_error()) { - const char *errorMsgPtr = olm_utility_last_error(utilityPtr); - errorMessageRetValue = env->NewStringUTF(errorMsgPtr); - LOGE("## verifyEd25519SignatureJni(): failure - olm_ed25519_verify Msg=%s",errorMsgPtr); - } - else - { - LOGD("## verifyEd25519SignatureJni(): success - result=%lu", static_cast<long unsigned int>(result)); - } - } - - // free alloc - if (signaturePtr) - { - env->ReleaseByteArrayElements(aSignatureBuffer, signaturePtr, JNI_ABORT); - } - - if (keyPtr) - { - env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT); - } - - if (messagePtr) - { - if (messageWasCopied) { - memset(messagePtr, 0, (size_t)env->GetArrayLength(aMessageBuffer)); - } - env->ReleaseByteArrayElements(aMessageBuffer, messagePtr, JNI_ABORT); - } - - return errorMessageRetValue; -} - -/** - * Compute the digest (SHA 256) for the message passed in parameter.<br> - * The digest value is the function return value. - * An exception is thrown if the operation fails. - * @param aMessage the message - * @return digest of the message. - **/ -JNIEXPORT jbyteArray OLM_UTILITY_FUNC_DEF(sha256Jni)(JNIEnv *env, jobject thiz, jbyteArray aMessageToHashBuffer) -{ - jbyteArray sha256Ret = 0; - - OlmUtility* utilityPtr = getUtilityInstanceId(env, thiz); - jbyte* messagePtr = NULL; - jboolean messageWasCopied = JNI_FALSE; - - LOGD("## sha256Jni(): IN"); - - if (!utilityPtr) - { - LOGE(" ## sha256Jni(): failure - invalid utility ptr=NULL"); - } - else if(!aMessageToHashBuffer) - { - LOGE(" ## sha256Jni(): failure - invalid message parameters "); - } - else if(!(messagePtr = env->GetByteArrayElements(aMessageToHashBuffer, &messageWasCopied))) - { - LOGE(" ## sha256Jni(): failure - message JNI allocation OOM"); - } - else - { - // get lengths - size_t messageLength = (size_t)env->GetArrayLength(aMessageToHashBuffer); - size_t hashLength = olm_sha256_length(utilityPtr); - void* hashValuePtr = malloc((hashLength)*sizeof(uint8_t)); - - if (!hashValuePtr) - { - LOGE("## sha256Jni(): failure - hash value allocation OOM"); - } - else - { - size_t result = olm_sha256(utilityPtr, - (void const *)messagePtr, - messageLength, - (void *)hashValuePtr, - hashLength); - if (result == olm_error()) - { - LOGE("## sha256Jni(): failure - hash creation Msg=%s",(const char *)olm_utility_last_error(utilityPtr)); - } - else - { - LOGD("## sha256Jni(): success - result=%lu hashValue=%.*s",static_cast<long unsigned int>(result), static_cast<int>(result), (char*)hashValuePtr); - sha256Ret = env->NewByteArray(result); - env->SetByteArrayRegion(sha256Ret, 0 , result, (jbyte*)hashValuePtr); - } - - free(hashValuePtr); - } - } - - if (messagePtr) - { - if (messageWasCopied) { - memset(messagePtr, 0, (size_t)env->GetArrayLength(aMessageToHashBuffer)); - } - env->ReleaseByteArrayElements(aMessageToHashBuffer, messagePtr, JNI_ABORT); - } - - return sha256Ret; -} diff --git a/android/olm-sdk/src/main/jni/olm_utility.h b/android/olm-sdk/src/main/jni/olm_utility.h deleted file mode 100644 index 07b5094..0000000 --- a/android/olm-sdk/src/main/jni/olm_utility.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2016 Vector Creations 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 _OLMUTILITY_H -#define _OLMUTILITY_H - -#include "olm_jni.h" -#include "olm/olm.h" - -#define OLM_UTILITY_FUNC_DEF(func_name) FUNC_DEF(OlmUtility,func_name) - - -#ifdef __cplusplus -extern "C" { -#endif -JNIEXPORT jlong OLM_UTILITY_FUNC_DEF(createUtilityJni)(JNIEnv *env, jobject thiz); -JNIEXPORT void OLM_UTILITY_FUNC_DEF(releaseUtilityJni)(JNIEnv *env, jobject thiz); -JNIEXPORT jstring OLM_UTILITY_FUNC_DEF(verifyEd25519SignatureJni)(JNIEnv *env, jobject thiz, jbyteArray aSignature, jbyteArray aKey, jbyteArray aMessage); -JNIEXPORT jbyteArray OLM_UTILITY_FUNC_DEF(sha256Jni)(JNIEnv *env, jobject thiz, jbyteArray aMessageToHash); -#ifdef __cplusplus -} -#endif - - - -#endif diff --git a/android/olm-sdk/src/main/res/values/strings.xml b/android/olm-sdk/src/main/res/values/strings.xml deleted file mode 100644 index 93bea1d..0000000 --- a/android/olm-sdk/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ -<resources> - <string name="app_name">OlmSdk</string> -</resources> diff --git a/android/settings.gradle b/android/settings.gradle deleted file mode 100644 index d11302c..0000000 --- a/android/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -include ':olm-sdk' diff --git a/cmake/OlmConfig.cmake.in b/cmake/OlmConfig.cmake.in deleted file mode 100644 index a7541f7..0000000 --- a/cmake/OlmConfig.cmake.in +++ /dev/null @@ -1,11 +0,0 @@ -get_filename_component(Olm_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) -include(CMakeFindDependencyMacro) - -list(APPEND CMAKE_MODULE_PATH ${Olm_CMAKE_DIR}) -list(REMOVE_AT CMAKE_MODULE_PATH -1) - -if(NOT TARGET Olm::olm) - include("${Olm_CMAKE_DIR}/OlmTargets.cmake") -endif() - -set(Olm_LIBRARIES Olm::olm) diff --git a/common.mk b/common.mk deleted file mode 100644 index 1bddbde..0000000 --- a/common.mk +++ /dev/null @@ -1,4 +0,0 @@ - -MAJOR := 3 -MINOR := 2 -PATCH := 1 diff --git a/exports.py b/exports.py deleted file mode 100755 index c8e97a7..0000000 --- a/exports.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python - -import sys -import re -import json - -expr = re.compile(r"(olm_[^( ]*)\(") - -exports = {'_free', '_malloc'} - -for f in sys.argv[1:]: - with open(f) as fp: - for line in fp: - matches = expr.search(line) - if matches is not None: - exports.add('_%s' % (matches.group(1),)) - -json.dump(sorted(exports), sys.stdout) diff --git a/fuzzers/README.rst b/fuzzers/README.rst deleted file mode 100644 index b6f5f9c..0000000 --- a/fuzzers/README.rst +++ /dev/null @@ -1,50 +0,0 @@ -Fuzzers -======= - -This directory contains a collection of fuzzing tools. Each tests a different -entry point to the code. - -Usage notes: - -1. Install AFL: - - .. code:: - - apt-get install afl - -2. Build the fuzzers: - - .. code:: - - make fuzzers - -3. Some of the tests (eg ``fuzz_decrypt`` and ``fuzz_group_decrypt``) require a - session file. You can create one by pickling an Olm session. - -4. Make some work directories: - - .. code:: - - mkdir -p fuzzing/in fuzzing/out - -5. Generate starting input: - - .. code:: - - echo "Test" > fuzzing/in/test - -6. Run the test under ``afl-fuzz``: - - .. code:: - - afl-fuzz -i fuzzing/in -o fuzzing/out -- \ - ./build/fuzzers/fuzz_<fuzzing_tool> [<test args>] - -7. To resume with the data produced by an earlier run: - - .. code:: - - afl-fuzz -i- -o existing_output_dir [...etc...] - -8. If it shows failures, pipe the failure case into - ``./build/fuzzers/debug_<fuzzing_tool>``, fix, and repeat. diff --git a/fuzzers/fuzz_decode_message.cpp b/fuzzers/fuzz_decode_message.cpp deleted file mode 100644 index 2ef734c..0000000 --- a/fuzzers/fuzz_decode_message.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "olm/message.hh" -#include "fuzzing.hh" - -int main(int argc, const char *argv[]) { - 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) - ); - olm::MessageReader * reader = new olm::MessageReader; - decode_message(*reader, message_buffer, message_length, 8); - free(message_buffer); - delete reader; -} diff --git a/fuzzers/fuzz_decrypt.cpp b/fuzzers/fuzz_decrypt.cpp deleted file mode 100644 index 0b48060..0000000 --- a/fuzzers/fuzz_decrypt.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "olm/olm.hh" - -#include "fuzzing.hh" - -int main(int argc, const char *argv[]) { - size_t ignored; - if (argc <= 3) { - const char * message = "Usage: decrypt: <session_key> <session_file>" - " <message_type>\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) - ); - - int message_type = atoi(argv[3]); - - 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_session_size()]; - OlmSession * session = olm_session(session_memory); - check_session(session, "Error unpickling session", olm_unpickle_session( - session, key, key_length, session_buffer, session_length - )); - - size_t max_length = check_session( - session, - "Error getting plaintext length", - olm_decrypt_max_plaintext_length( - session, message_type, tmp_buffer, message_length - ) - ); - - uint8_t plaintext[max_length]; - - size_t length = check_session( - session, "Error decrypting message", olm_decrypt( - session, message_type, - message_buffer, message_length, - plaintext, max_length - ) - ); - - ignored = write(STDOUT_FILENO, plaintext, length); - ignored = write(STDOUT_FILENO, "\n", 1); - return ignored; -} diff --git a/fuzzers/fuzz_group_decrypt.cpp b/fuzzers/fuzz_group_decrypt.cpp deleted file mode 100644 index bb12d0e..0000000 --- a/fuzzers/fuzz_group_decrypt.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#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; -} diff --git a/fuzzers/fuzz_unpickle_account.cpp b/fuzzers/fuzz_unpickle_account.cpp deleted file mode 100644 index 12c6d9b..0000000 --- a/fuzzers/fuzz_unpickle_account.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#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; -} diff --git a/fuzzers/fuzz_unpickle_session.cpp b/fuzzers/fuzz_unpickle_session.cpp deleted file mode 100644 index 6edbc96..0000000 --- a/fuzzers/fuzz_unpickle_session.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "olm/session.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::Session * session = new olm::Session; - unpickle(pickle_buffer, pickle_buffer + pickle_length, *session); - free(pickle_buffer); - delete session; -} diff --git a/fuzzers/include/fuzzing.hh b/fuzzers/include/fuzzing.hh deleted file mode 100644 index b27c396..0000000 --- a/fuzzers/include/fuzzing.hh +++ /dev/null @@ -1,82 +0,0 @@ -#include "olm/olm.hh" - -#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> - - -ssize_t read_file( - int fd, - uint8_t **buffer -) { - size_t buffer_size = 4096; - uint8_t * current_buffer = (uint8_t *) malloc(buffer_size); - if (current_buffer == NULL) return -1; - size_t buffer_pos = 0; - while (1) { - ssize_t count = read( - fd, current_buffer + buffer_pos, buffer_size - buffer_pos - ); - if (count < 0) break; - if (count == 0) { - uint8_t * return_buffer = (uint8_t *) realloc(current_buffer, buffer_pos); - if (return_buffer == NULL) break; - *buffer = return_buffer; - return buffer_pos; - } - buffer_pos += count; - if (buffer_pos == buffer_size) { - buffer_size *= 2; - uint8_t * new_buffer = (uint8_t *) realloc(current_buffer, buffer_size); - if (new_buffer == NULL) break; - current_buffer = new_buffer; - } - } - free(current_buffer); - return -1; -} - -template<typename T> -T check_errno( - const char * message, - T value -) { - if (value == T(-1)) { - perror(message); - exit(1); - } - return value; -} - -template<typename T, typename F> -size_t check_error( - F f, - T * object, - const char * message, - size_t value -) { - if (value == olm_error()) { - const char * olm_message = f(object); - ssize_t ignored; - ignored = write(STDERR_FILENO, message, strlen(message)); - ignored = write(STDERR_FILENO, ": ", 2); - ignored = write(STDERR_FILENO, olm_message, strlen(olm_message)); - ignored = write(STDERR_FILENO, "\n", 1); - exit(2); - return ignored; - } - return value; -} - -size_t check_session( - OlmSession * session, - const char * message, - size_t value -) { - return check_error(olm_session_last_error, session, message, value); -} diff --git a/javascript/.gitignore b/javascript/.gitignore deleted file mode 100644 index 1533e1b..0000000 --- a/javascript/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -/exported_functions.json -/node_modules -/npm-debug.log -/olm.js -/olm_legacy.js -/olm.wasm -/reports diff --git a/javascript/README.md b/javascript/README.md deleted file mode 100644 index bdf0224..0000000 --- a/javascript/README.md +++ /dev/null @@ -1,46 +0,0 @@ -Olm -=== - -Note: before using any of the olm functions, you must call `Olm.init()`, and -wait for the promise to resolve, otherwise you will get errors like: -`Uncaught TypeError: Olm.Account is not a constructor` - -Example: - - var alice = new Olm.Account(); - var bob = new Olm.Account(); - alice.create(); - bob.create(); - bob.generate_one_time_keys(1); - - var bobs_id_keys = JSON.parse(bob.identity_keys()); - var bobs_id_key = bobs_id_keys.curve25519; - var bobs_ot_keys = JSON.parse(bob.one_time_keys()); - for (key in bobs_ot_keys.curve25519) { - var bobs_ot_key = bobs_ot_keys.curve25519[key]; - } - - alice_session = new Olm.Session(); - alice_session.create_outbound(alice, bobs_id_key, bobs_ot_key); - alice_message = a_session.encrypt("Hello"); - - bob_session.create_inbound(bob, bob_message); - var plaintext = bob_session.decrypt(message_1.type, bob_message); - bob.remove_one_time_keys(bob_session); - - -Group chat: - - var outbound_session = new Olm.OutboundGroupSession(); - outbound_session.create(); - - // exchange these over a secure channel - var session_id = group_session.session_id(); - var session_key = group_session.session_key(); - var message_index = group_session.message_index(); - - var inbound_session = new Olm.InboundGroupSession(); - inbound_session.create(message_index, session_key); - - var ciphertext = outbound_session.encrypt("Hello"); - var plaintext = inbound_session.decrypt(ciphertext); diff --git a/javascript/demo/demo.css b/javascript/demo/demo.css deleted file mode 100644 index bf07df1..0000000 --- a/javascript/demo/demo.css +++ /dev/null @@ -1,8 +0,0 @@ -div.user { - width: 500px; - float: left; - overflow: scroll; - margin: 0px 20px 0px 0px; - border: 1px solid black; - padding: 5px; -}
\ No newline at end of file diff --git a/javascript/demo/group_demo.html b/javascript/demo/group_demo.html deleted file mode 100644 index d93a7cd..0000000 --- a/javascript/demo/group_demo.html +++ /dev/null @@ -1,112 +0,0 @@ -<html> - <head> - <link rel="stylesheet" type="text/css" href="demo.css"/> - <script src="../olm.js"></script> - <script src="group_demo.js"></script> - </head> -<body> -<div id="user1" class="user"> - <h1>User1</h1> - - <textarea class="user_plain_input"></textarea> - <button class="user_encrypt">Encrypt</button> - - <h2>Outgoing</h2> - - <h3>One-to-one output</h3> - <div class="user_cipher_output"></div> - - <h3>Group output</h3> - <div class="group_output"></div> - - <h2>Incoming</h2> - - <h3>One-to-one Received</h3> - <div class="user_cipher_input"></div> - - <h3>Group received</h3> - <div class="group_input"></div> - - <h2>Tasks</h2> - <div class="user_progress"></div> -</div> - -<div id="user2" class="user"> - <h1>User 2</h1> - - <textarea class="user_plain_input"></textarea> - <button class="user_encrypt">Encrypt</button> - - <h2>Outgoing</h2> - - <h3>One-to-one output</h3> - <div class="user_cipher_output"></div> - - <h3>Group output</h3> - <div class="group_output"></div> - - <h2>Incoming</h2> - - <h3>One-to-one Received</h3> - <div class="user_cipher_input"></div> - - <h3>Group received</h3> - <div class="group_input"></div> - - <h2>Tasks</h2> - <div class="user_progress"></div> -</div> - -<div id="user3" class="user"> - <h1>User 3</h1> - - <textarea class="user_plain_input"></textarea> - <button class="user_encrypt">Encrypt</button> - - <h2>Outgoing</h2> - - <h3>One-to-one output</h3> - <div class="user_cipher_output"></div> - - <h3>Group output</h3> - <div class="group_output"></div> - - <h2>Incoming</h2> - - <h3>One-to-one Received</h3> - <div class="user_cipher_input"></div> - - <h3>Group received</h3> - <div class="group_input"></div> - - <h2>Tasks</h2> - <div class="user_progress"></div> -</div> - -<div id="user4" class="user"> - <h1>User 4</h1> - - <textarea class="user_plain_input"></textarea> - <button class="user_encrypt">Encrypt</button> - - <h2>Outgoing</h2> - - <h3>One-to-one output</h3> - <div class="user_cipher_output"></div> - - <h3>Group output</h3> - <div class="group_output"></div> - - <h2>Incoming</h2> - - <h3>One-to-one Received</h3> - <div class="user_cipher_input"></div> - - <h3>Group received</h3> - <div class="group_input"></div> - - <h2>Tasks</h2> - <div class="user_progress"></div> -</div> -</body> -</html> diff --git a/javascript/demo/group_demo.js b/javascript/demo/group_demo.js deleted file mode 100644 index 44b8166..0000000 --- a/javascript/demo/group_demo.js +++ /dev/null @@ -1,506 +0,0 @@ -/* Javascript parts of the group demo. To use, load group_demo.html in your - * browser. - */ - -function buttonElement(buttonLabel, clickHandler) { - var button = document.createElement("button"); - button.appendChild(document.createTextNode(buttonLabel)); - button.addEventListener("click", clickHandler, false); - return button; -} - -function buttonsAndText(textContent, buttonLabelToHandlerMap) { - var el = document.createElement("div"); - for (var label in buttonLabelToHandlerMap) { - if (!buttonLabelToHandlerMap.hasOwnProperty(label)) { - continue; - } - var handler = buttonLabelToHandlerMap[label]; - var button = buttonElement(label, handler); - el.appendChild(button); - } - - var message_element = document.createElement("tt"); - el.appendChild(message_element); - - var content = document.createTextNode(textContent); - message_element.appendChild(content); - - return el; -} - -function buttonAndTextElement(buttonLabel, textContent, clickHandler) { - var buttonMap = {}; - buttonMap[buttonLabel] = clickHandler; - return buttonsAndText(textContent, buttonMap); -} - -function DemoUser(name) { - this.name = name; - this.olmAccount = new Olm.Account(); - this.olmAccount.create(); - - this.idKey = this.getIdKeys()["curve25519"]; - - /* the people in our chat, indexed by their Curve25519 identity key. - */ - this.peers = {}; - - /* the Ed25519 signing key for each peer, indexed by their Curve25519 id key - */ - this.peerSigningKeys = {}; - - /* for each peer, a one-to-one session - indexed by id key and created on - * demand */ - this.peerSessions = {}; - - /* for each peer, info on their sender session - indexed by id key and - * session id */ - this.peerGroupSessions = {}; - - /* our outbound group session */ - this.groupSession = undefined; - - /* a list of pending tasks */ - this.tasks = []; - this.taskWorker = undefined; - - /* the operations our peers are allowed to do on us */ - var publicOps = [ - "getIdKeys", "getOneTimeKey", - "receiveOneToOne", "receiveGroup", - ]; - - this.remoteOps = {}; - for (var i=0; i<publicOps.length; i++) { - var op = publicOps[i]; - this.remoteOps[op] = this[op].bind(this); - } -} - -DemoUser.prototype._progress = function(message) { - var progress = this.progressElement; - - var message_element = document.createElement("pre"); - var start_content = document.createTextNode(message + "..."); - function start() { - message_element.appendChild(start_content); - progress.appendChild(message_element); - } - function done(res) { - var done_content = document.createTextNode(message + "..." + res); - message_element.replaceChild(done_content, start_content); - } - return {start:start, done:done}; -}; - -DemoUser.prototype._do_tasks = function() { - var self = this; - var task = self.tasks.shift(); - var desc = task[0]; - var func = task[1]; - var callback = task[2]; - - var p = self._progress(desc); - p.start(); - - function done() { - p.done("Done"); - - if (callback) { - try { - callback.apply(undefined, arguments) - } catch (e) { - console.error("Uncaught exception in callback", e.stack || e); - } - } - - start_tasks(); - } - - // sleep 50ms before actually doing the task - self.taskWorker = window.setTimeout(function() { - try { - task[1](done); - } catch (e) { - console.error("Uncaught exception in task", e.stack || e); - p.done("Failed: "+e); - start_tasks(); - } - }, 50); - - - function start_tasks() { - if (self.tasks.length == 0) { - self.taskWorker = undefined; - return; - } - - self.taskWorker = window.setTimeout(self._do_tasks.bind(self), 50); - } -} - -/** - * add a function "task" to this user's queue of things to do. - * - * task is called with a single argument 'done' which is a function to call - * once the task is complete. - * - * 'callback' is called once the task is complete, with any arguments that - * were passed to 'done'. - */ -DemoUser.prototype.addTask = function(description, task, callback) { - this.tasks.push([description, task, callback]); - if(!this.taskWorker) { - this._do_tasks(); - } -}; - -DemoUser.prototype.addPeer = function(peerOps) { - var keys = peerOps.getIdKeys(); - var id = keys["curve25519"]; - this.peers[id] = peerOps; - this.peerSigningKeys[id] = keys["ed25519"]; -}; - -DemoUser.prototype.getIdKeys = function() { - return JSON.parse(this.olmAccount.identity_keys()); -}; - -DemoUser.prototype.getOneTimeKey = function() { - var self = this; - self.olmAccount.generate_one_time_keys(1); - var keys = JSON.parse(self.olmAccount.one_time_keys()).curve25519; - for (key_id in keys) { - if (keys.hasOwnProperty(key_id)) { - self.olmAccount.mark_keys_as_published(); - return keys[key_id]; - } - } - throw new Error("No one-time-keys generated"); -}; - -/* ************************************************************************ - * - * one-to-one messaging - */ - -/** - * retrieve, or initiate, a one-to-one session to a given peer - */ -DemoUser.prototype.getPeerSession = function(peerId, callback) { - var self = this; - - if (this.peerSessions[peerId]) { - callback(this.peerSessions[peerId]); - return; - } - - var peer = this.peers[peerId]; - this.addTask("get peer keys", function(done) { - key = peer.getOneTimeKey(); - done(key); - }, function(ot_key) { - self.addTask("create peer session", function(done) { - var session = new Olm.Session(); - session.create_outbound(self.olmAccount, peerId, ot_key); - self.peerSessions[peerId] = session; - done(session); - }, callback); - }); -}; - -/** - * encrypt a one-to-one message and prepare it for sending to a peer - */ -DemoUser.prototype.sendToPeer = function(peerId, message, callback) { - var self = this; - this.getPeerSession(peerId, function(session) { - self.addTask("encrypt one-to-one message", function(done) { - var encrypted = session.encrypt(message); - var packet = { - sender_key: self.idKey, - ciphertext: encrypted, - }; - var json = JSON.stringify(packet); - - var el = buttonAndTextElement("send", json, function(ev) { - self.peers[peerId].receiveOneToOne(json); - }); - self.cipherOutputDiv.appendChild(el); - done(); - }, callback); - }); -}; - -/** - * handler for receiving a one-to-one message - */ -DemoUser.prototype.receiveOneToOne = function(jsonpacket) { - var self = this; - var el = buttonAndTextElement("decrypt", jsonpacket, function(ev) { - var sender = JSON.parse(jsonpacket).sender_key; - self.decryptOneToOne(jsonpacket, function(result) { - - var el2 = document.createElement("tt"); - el.appendChild(el2); - - var content = document.createTextNode(" -> "+result); - el2.appendChild(content); - - var body = JSON.parse(result); - - // create a new inbound session if we don't yet have one - if (!self.peerGroupSessions[sender] || - !self.peerGroupSessions[sender][body.session_id]) { - self.createInboundSession( - sender, body.session_id, body.session_key - ); - } - }); - }); - this.cipherInputDiv.appendChild(el); -}; - -/** - * add a task to decrypt a one-to-one message. Calls the callback with the - * decrypted plaintext - */ -DemoUser.prototype.decryptOneToOne = function(jsonpacket, callback) { - var self = this; - self.addTask("decrypt one-to-one message", function(done) { - var packet = JSON.parse(jsonpacket); - var peerId = packet.sender_key; - - var session = self.peerSessions[peerId]; - var plaintext; - if (session) { - plaintext = session.decrypt(packet.ciphertext.type, packet.ciphertext.body); - done(plaintext); - return; - } - - if (packet.ciphertext.type != 0) { - throw new Error("Unknown one-to-one session"); - } - - session = new Olm.Session(); - session.create_inbound(self.olmAccount, packet.ciphertext.body); - self.peerSessions[peerId] = session; - plaintext = session.decrypt(packet.ciphertext.type, packet.ciphertext.body); - done(plaintext); - }, callback) -}; - -/* ************************************************************************ - * - * group messaging - */ - - -/** - * retrieve, or initiate, an outbound group session - */ -DemoUser.prototype.getGroupSession = function() { - if (this.groupSession) { - return this.groupSession; - } - - this.groupSession = new Olm.OutboundGroupSession(); - this.groupSession.create(); - - var keymsg = { - "session_id": this.groupSession.session_id(), - "session_key": this.groupSession.session_key(), - "message_index": this.groupSession.message_index(), - }; - var jsonmsg = JSON.stringify(keymsg); - - for (var peer in this.peers) { - if (!this.peers.hasOwnProperty(peer)) { - continue; - } - this.sendToPeer(peer, jsonmsg); - } - - return this.groupSession; -}; - -/** - * add a task to create an inbound group session - */ -DemoUser.prototype.createInboundSession = function( - peer_id, session_id, session_key, callback -) { - var self = this; - this.addTask("init inbound session", function(done) { - session = new Olm.InboundGroupSession(); - session.create(session_key); - if (!self.peerGroupSessions[peer_id]) { - self.peerGroupSessions[peer_id] = {}; - } - if (session_id != session.session_id()) { - throw new Error("Mismatched session_ids"); - } - self.peerGroupSessions[peer_id][session_id] = session; - done(session); - }, callback); -}; - -/** - * handler for receiving a group message - */ -DemoUser.prototype.receiveGroup = function(jsonpacket) { - var self = this; - var el = buttonAndTextElement("decrypt", jsonpacket, function(ev) { - self.decryptGroup(jsonpacket, function(result) { - var el2 = document.createElement("tt"); - el.appendChild(el2); - - var content = document.createTextNode(" -> "+result); - el2.appendChild(content); - }); - }); - this.groupInputDiv.appendChild(el); -}; - -/** - * add a task to decrypt a received group message. Calls the callback with the - * decrypted plaintext - */ -DemoUser.prototype.decryptGroup = function(jsonpacket, callback) { - var self = this; - this.addTask("decrypt group message", function(done) { - var packet = JSON.parse(jsonpacket); - - var sender = packet.sender_key; - var session_id = packet.session_id; - - var sender_signing_key = self.peerSigningKeys[sender]; - if (!sender_signing_key) { - throw new Error("No known signing key for sender "+sender); - } - - var olmUtility = new Olm.Utility(); - olmUtility.ed25519_verify( - sender_signing_key, packet.body, packet.signature - ); - - var peer_sessions = self.peerGroupSessions[sender]; - if (!peer_sessions) { - throw new Error("No sessions for sender "+sender); - } - - var session = peer_sessions[session_id]; - if (!session) { - throw new Error("Unknown session id " + session_id); - } - - var result = session.decrypt(packet.body); - done(result.plaintext); - }, callback); -}; - - - -/** - * add a task to encrypt, and prepare for sending, a group message. - * - * Will create a group session if necessary - */ -DemoUser.prototype.encrypt = function(message) { - var self = this; - var session = this.getGroupSession(); - - function sendJsonToPeers(json) { - for (var peer in self.peers) { - if (!self.peers.hasOwnProperty(peer)) { - continue; - } - self.peers[peer].receiveGroup(json); - } - } - - - self.addTask("encrypt group message", function(done) { - var encrypted = session.encrypt(message); - var signature = self.olmAccount.sign(encrypted); - - var packet = { - sender_key: self.idKey, - session_id: session.session_id(), - body: encrypted, - signature: signature, - }; - var json = JSON.stringify(packet); - - var el = buttonsAndText(json, { - send: function(ev) { - sendJsonToPeers(json); - }, - "send corrupted": function(ev) { - var p = JSON.parse(json); - p.body += " "; - sendJsonToPeers(JSON.stringify(p)); - }, - }); - self.groupOutputDiv.appendChild(el); - done(); - }); -}; - - -/* ************************************************************************** */ - -function initUserDiv(demoUser, div) { - demoUser.progressElement = div.getElementsByClassName("user_progress")[0]; - demoUser.cipherOutputDiv = div.getElementsByClassName("user_cipher_output")[0]; - demoUser.cipherInputDiv = div.getElementsByClassName("user_cipher_input")[0]; - demoUser.groupOutputDiv = div.getElementsByClassName("group_output")[0]; - demoUser.groupInputDiv = div.getElementsByClassName("group_input")[0]; - - var plain_input = div.getElementsByClassName("user_plain_input")[0]; - var encrypt = div.getElementsByClassName("user_encrypt")[0]; - - encrypt.addEventListener("click", function() { - demoUser.encrypt(plain_input.value); - }, false); - -} - -function startDemo() { - var user1 = new DemoUser(); - initUserDiv(user1, document.getElementById("user1")); - - var user2 = new DemoUser(); - initUserDiv(user2, document.getElementById("user2")); - - var user3 = new DemoUser(); - initUserDiv(user3, document.getElementById("user3")); - - var user4 = new DemoUser(); - initUserDiv(user4, document.getElementById("user4")); - - user1.addPeer(user2.remoteOps); - user1.addPeer(user3.remoteOps); - user1.addPeer(user4.remoteOps); - - user2.addPeer(user1.remoteOps); - user2.addPeer(user3.remoteOps); - user2.addPeer(user4.remoteOps); - - user3.addPeer(user1.remoteOps); - user3.addPeer(user2.remoteOps); - user3.addPeer(user4.remoteOps); - - user4.addPeer(user1.remoteOps); - user4.addPeer(user2.remoteOps); - user4.addPeer(user3.remoteOps); -} - - -document.addEventListener("DOMContentLoaded", function() { - Olm.init().then(function() { - startDemo(); - }); -}, false); diff --git a/javascript/demo/one_to_one_demo.html b/javascript/demo/one_to_one_demo.html deleted file mode 100644 index a225e4a..0000000 --- a/javascript/demo/one_to_one_demo.html +++ /dev/null @@ -1,147 +0,0 @@ -<html> -<head> -<script src="../olm.js"></script> -<script> -document.addEventListener("DOMContentLoaded", function() { - Olm.init().then(function() { - demo(); - }); -}, false); - -function demo() { - function progress(who, message) { - var message_element = document.createElement("pre"); - var progress = document.getElementById(who + "_progress"); - var start_content = document.createTextNode(message + "..."); - var done_content = document.createTextNode(message + "... Done"); - function start() { - message_element.appendChild(start_content); - progress.appendChild(message_element); - } - function done() { - message_element.replaceChild(done_content, start_content); - } - return {start:start, done:done}; - } - - window.alice = new Olm.Account(); - window.bob = new Olm.Account(); - var a_session = new Olm.Session(); - var b_session = new Olm.Session(); - var message_1; - var tasks = []; - - tasks.push(["alice", "Creating account", function() { alice.create() }]); - tasks.push(["bob", "Creating account", function() { bob.create() }]); - tasks.push(["bob", "Generate one time keys", function() { - bob.generate_one_time_keys(1); - }]); - tasks.push(["alice", "Create outbound session", function() { - var bobs_id_keys = JSON.parse(bob.identity_keys()); - var bobs_id_key = bobs_id_keys.curve25519; - var bobs_ot_keys = JSON.parse(bob.one_time_keys()); - var bobs_ot_key; - for (key in bobs_ot_keys.curve25519) { - bobs_ot_key = bobs_ot_keys.curve25519[key]; - } - a_session.create_outbound(alice, bobs_id_key, bobs_ot_key); - }]); - tasks.push(["alice", "Encrypt first message", function() { - message_1 = a_session.encrypt(""); - }]); - tasks.push(["bob", "Create inbound session", function() { - b_session.create_inbound(bob, message_1.body); - }]); - tasks.push(["bob", "Decrypt first message", function() { - b_session.decrypt(message_1.type, message_1.body); - }]); - - function glue_encrypt(from, to, from_session) { - var plain_input = document.getElementById(from + "_plain_input"); - var cipher_output = document.getElementById(from + "_cipher_output"); - var cipher_input = document.getElementById(to + "_cipher_input"); - var encrypt = document.getElementById(from + "_encrypt"); - - encrypt.addEventListener("click", function() { - var message = from_session.encrypt(plain_input.value); - var message_element = document.createElement("pre"); - var content = document.createTextNode(JSON.stringify(message)); - message_element.appendChild(content); - cipher_output.appendChild(message_element); - message_element.addEventListener("click", function() { - cipher_input.value = JSON.stringify(message); - }, false); - }, false); - } - - function glue_decrypt(to, to_session) { - var cipher_input = document.getElementById(to + "_cipher_input"); - var plain_output = document.getElementById(to + "_plain_output"); - var decrypt = document.getElementById(to + "_decrypt"); - - decrypt.addEventListener("click", function() { - var message = JSON.parse(cipher_input.value); - try { - var plaintext = to_session.decrypt(message.type, message.body); - } catch (e) { - var plaintext = "ERROR: " + e.message; - } - var message_element = document.createElement("pre"); - var message_content = document.createTextNode(plaintext); - message_element.appendChild(message_content); - plain_output.appendChild(message_element); - }, false); - } - - function do_tasks(next) { - if (tasks.length > 0) { - var task = tasks.shift(); - var p = progress(task[0], task[1]) - p.start(); - window.setTimeout(function() { - task[2](); - p.done(); - window.setTimeout(do_tasks, 50, next); - }, 50) - } else { - next(); - } - } - - do_tasks(function() { - glue_encrypt("alice", "bob", a_session); - glue_decrypt("bob", b_session); - - glue_encrypt("bob", "alice", b_session); - glue_decrypt("alice", a_session); - }); -} - -</script> -<body> -<div id="alice"> - <h1>Alice</h1> - <div id="alice_progress"></div> - <h2>Encryption</h2> - <textarea id="alice_plain_input"></textarea> - <button id="alice_encrypt">Encrypt</button> - <div id="alice_cipher_output"></div> - <h2>Decryption</h2> - <textarea id="alice_cipher_input"></textarea> - <button id="alice_decrypt">Decrypt</button> - <div id="alice_plain_output"></div> -</div> -<div id="bob"> - <h1>Bob</h1> - <div id="bob_progress"></div> - <h2>Encryption</h2> - <textarea id="bob_plain_input"></textarea> - <button id="bob_encrypt">Encrypt</button> - <div id="bob_cipher_output"></div> - <h2>Decryption</h2> - <textarea id="bob_cipher_input"></textarea> - <button id="bob_decrypt">Decrypt</button> - <div id="bob_plain_output"></div> -</div> -</body> -</html> diff --git a/javascript/externs.js b/javascript/externs.js deleted file mode 100644 index 752e937..0000000 --- a/javascript/externs.js +++ /dev/null @@ -1,4 +0,0 @@ -var OLM_OPTIONS; -var olm_exports; -var onInitSuccess; -var onInitFail; diff --git a/javascript/index.d.ts b/javascript/index.d.ts deleted file mode 100644 index 141f695..0000000 --- a/javascript/index.d.ts +++ /dev/null @@ -1,129 +0,0 @@ -/* -Copyright 2020 The Matrix.org Foundation C.I.C. - -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. -*/ - -export as namespace Olm; - -declare class Account { - constructor(); - free(); - create(); - identity_keys(): string; - sign(message: string | Uint8Array): string; - one_time_keys(): string; - mark_keys_as_published(); - max_number_of_one_time_keys(): number; - generate_one_time_keys(number_of_keys: number); - remove_one_time_keys(session: Session); - generate_fallback_key(); - fallback_key(): string; - pickle(key: string | Uint8Array): string; - unpickle(key: string | Uint8Array, pickle: string); -} - -declare class Session { - constructor(); - free(): void; - pickle(key: string | Uint8Array): string; - unpickle(key: string | Uint8Array, pickle: string); - create_outbound( - account: Account, their_identity_key: string, their_one_time_key: string, - ): void; - create_inbound(account: Account, one_time_key_message: string): void; - create_inbound_from( - account: Account, identity_key: string, one_time_key_message: string, - ): void; - session_id(): string; - has_received_message(): boolean; - matches_inbound(one_time_key_message: string): boolean; - matches_inbound_from(identity_key: string, one_time_key_message: string): boolean; - encrypt(plaintext: string): object; - decrypt(message_type: number, message: string): string; - describe(): string; -} - -declare class Utility { - constructor(); - free(): void; - sha256(input: string | Uint8Array): string; - ed25519_verify(key: string, message: string | Uint8Array, signature: string): void; -} - -declare class InboundGroupSession { - constructor(); - free(): void; - pickle(key: string | Uint8Array): string; - unpickle(key: string | Uint8Array, pickle: string); - create(session_key: string): string; - import_session(session_key: string): string; - decrypt(message: string): object; - session_id(): string; - first_known_index(): number; - export_session(message_index: number): string; -} - -declare class OutboundGroupSession { - constructor(); - free(): void; - pickle(key: string | Uint8Array): string; - unpickle(key: string | Uint8Array, pickle: string); - create(): void; - encrypt(plaintext: string): string; - session_id(): string; - session_key(): string; - message_index(): number; -} - -declare class PkEncryption { - constructor(); - free(): void; - set_recipient_key(key: string): void; - encrypt(plaintext: string): object; -} - -declare class PkDecryption { - constructor(); - free(): void; - init_with_private_key(key: Uint8Array): string; - generate_key(): string; - get_private_key(): Uint8Array; - pickle(key: string | Uint8Array): string; - unpickle(key: string | Uint8Array, pickle: string): string; - decrypt(ephemeral_key: string, mac: string, ciphertext: string): string; -} - -declare class PkSigning { - constructor(); - free(): void; - init_with_seed(seed: Uint8Array): string; - generate_seed(): Uint8Array; - sign(message: string): string; -} - -declare class SAS { - constructor(); - free(): void; - get_pubkey(): string; - set_their_key(their_key: string): void; - generate_bytes(info: string, length: number): Uint8Array; - calculate_mac(input: string, info: string): string; - calculate_mac_long_kdf(input: string, info: string): string; -} - -export function init(opts?: object): Promise<void>; - -export function get_library_version(): [number, number, number]; - -export const PRIVATE_KEY_LENGTH: number; diff --git a/javascript/olm_inbound_group_session.js b/javascript/olm_inbound_group_session.js deleted file mode 100644 index 423d2b1..0000000 --- a/javascript/olm_inbound_group_session.js +++ /dev/null @@ -1,180 +0,0 @@ -function InboundGroupSession() { - var size = Module['_olm_inbound_group_session_size'](); - this.buf = malloc(size); - this.ptr = Module['_olm_inbound_group_session'](this.buf); -} - -function inbound_group_session_method(wrapped) { - return function() { - var result = wrapped.apply(this, arguments); - if (result === OLM_ERROR) { - var message = UTF8ToString( - Module['_olm_inbound_group_session_last_error'](arguments[0]) - ); - throw new Error("OLM." + message); - } - return result; - } -} - -InboundGroupSession.prototype['free'] = function() { - Module['_olm_clear_inbound_group_session'](this.ptr); - free(this.ptr); -} - -InboundGroupSession.prototype['pickle'] = restore_stack(function(key) { - var key_array = array_from_string(key); - var pickle_length = inbound_group_session_method( - Module['_olm_pickle_inbound_group_session_length'] - )(this.ptr); - var key_buffer = stack(key_array); - var pickle_buffer = stack(pickle_length + NULL_BYTE_PADDING_LENGTH); - try { - inbound_group_session_method(Module['_olm_pickle_inbound_group_session'])( - this.ptr, key_buffer, key_array.length, pickle_buffer, pickle_length - ); - } finally { - // clear out copies of the pickle key - bzero(key_buffer, key_array.length) - for (var i = 0; i < key_array.length; i++) { - key_array[i] = 0; - } - } - return UTF8ToString(pickle_buffer, pickle_length); -}); - -InboundGroupSession.prototype['unpickle'] = restore_stack(function(key, pickle) { - var key_array = array_from_string(key); - var key_buffer = stack(key_array); - var pickle_array = array_from_string(pickle); - var pickle_buffer = stack(pickle_array); - try { - inbound_group_session_method(Module['_olm_unpickle_inbound_group_session'])( - this.ptr, key_buffer, key_array.length, pickle_buffer, - pickle_array.length - ); - } finally { - // clear out copies of the pickle key - bzero(key_buffer, key_array.length) - for (var i = 0; i < key_array.length; i++) { - key_array[i] = 0; - } - } -}); - -InboundGroupSession.prototype['create'] = restore_stack(function(session_key) { - var key_array = array_from_string(session_key); - var key_buffer = stack(key_array); - - try { - inbound_group_session_method(Module['_olm_init_inbound_group_session'])( - this.ptr, key_buffer, key_array.length - ); - } finally { - // clear out copies of the key - bzero(key_buffer, key_array.length) - for (var i = 0; i < key_array.length; i++) { - key_array[i] = 0; - } - } -}); - -InboundGroupSession.prototype['import_session'] = restore_stack(function(session_key) { - var key_array = array_from_string(session_key); - var key_buffer = stack(key_array); - - try { - inbound_group_session_method(Module['_olm_import_inbound_group_session'])( - this.ptr, key_buffer, key_array.length - ); - } finally { - // clear out copies of the key - bzero(key_buffer, key_array.length) - for (var i = 0; i < key_array.length; i++) { - key_array[i] = 0; - } - } -}); - -InboundGroupSession.prototype['decrypt'] = restore_stack(function( - message -) { - var message_buffer, plaintext_buffer, plaintext_length; - - try { - message_buffer = malloc(message.length); - writeAsciiToMemory(message, message_buffer, true); - - var max_plaintext_length = inbound_group_session_method( - Module['_olm_group_decrypt_max_plaintext_length'] - )(this.ptr, message_buffer, message.length); - - // caculating the length destroys the input buffer, so we need to re-copy it. - writeAsciiToMemory(message, message_buffer, true); - - plaintext_buffer = malloc(max_plaintext_length + NULL_BYTE_PADDING_LENGTH); - var message_index = stack(4); - - plaintext_length = inbound_group_session_method( - Module["_olm_group_decrypt"] - )( - this.ptr, - message_buffer, message.length, - plaintext_buffer, max_plaintext_length, - message_index - ); - - // UTF8ToString requires a null-terminated argument, so add the - // null terminator. - setValue( - plaintext_buffer+plaintext_length, - 0, "i8" - ); - - return { - "plaintext": UTF8ToString(plaintext_buffer, plaintext_length), - "message_index": getValue(message_index, "i32") - } - } finally { - if (message_buffer !== undefined) { - free(message_buffer); - } - if (plaintext_buffer !== undefined) { - // don't leave a copy of the plaintext in the heap. - bzero(plaintext_buffer, plaintext_length); - free(plaintext_buffer); - } - } -}); - -InboundGroupSession.prototype['session_id'] = restore_stack(function() { - var length = inbound_group_session_method( - Module['_olm_inbound_group_session_id_length'] - )(this.ptr); - var session_id = stack(length + NULL_BYTE_PADDING_LENGTH); - inbound_group_session_method(Module['_olm_inbound_group_session_id'])( - this.ptr, session_id, length - ); - return UTF8ToString(session_id, length); -}); - -InboundGroupSession.prototype['first_known_index'] = restore_stack(function() { - return inbound_group_session_method( - Module['_olm_inbound_group_session_first_known_index'] - )(this.ptr); -}); - -InboundGroupSession.prototype['export_session'] = restore_stack(function(message_index) { - var key_length = inbound_group_session_method( - Module['_olm_export_inbound_group_session_length'] - )(this.ptr); - var key = stack(key_length + NULL_BYTE_PADDING_LENGTH); - outbound_group_session_method(Module['_olm_export_inbound_group_session'])( - this.ptr, key, key_length, message_index - ); - var key_str = UTF8ToString(key, key_length); - bzero(key, key_length); // clear out a copy of the key - return key_str; -}); - -olm_exports['InboundGroupSession'] = InboundGroupSession; diff --git a/javascript/olm_outbound_group_session.js b/javascript/olm_outbound_group_session.js deleted file mode 100644 index e4852c1..0000000 --- a/javascript/olm_outbound_group_session.js +++ /dev/null @@ -1,147 +0,0 @@ -function OutboundGroupSession() { - var size = Module['_olm_outbound_group_session_size'](); - this.buf = malloc(size); - this.ptr = Module['_olm_outbound_group_session'](this.buf); -} - -function outbound_group_session_method(wrapped) { - return function() { - var result = wrapped.apply(this, arguments); - if (result === OLM_ERROR) { - var message = UTF8ToString( - Module['_olm_outbound_group_session_last_error'](arguments[0]) - ); - throw new Error("OLM." + message); - } - return result; - } -} - -OutboundGroupSession.prototype['free'] = function() { - Module['_olm_clear_outbound_group_session'](this.ptr); - free(this.ptr); -} - -OutboundGroupSession.prototype['pickle'] = restore_stack(function(key) { - var key_array = array_from_string(key); - var pickle_length = outbound_group_session_method( - Module['_olm_pickle_outbound_group_session_length'] - )(this.ptr); - var key_buffer = stack(key_array); - var pickle_buffer = stack(pickle_length + NULL_BYTE_PADDING_LENGTH); - try { - outbound_group_session_method(Module['_olm_pickle_outbound_group_session'])( - this.ptr, key_buffer, key_array.length, pickle_buffer, pickle_length - ); - } finally { - // clear out copies of the pickle key - bzero(key_buffer, key_array.length) - for (var i = 0; i < key_array.length; i++) { - key_array[i] = 0; - } - } - return UTF8ToString(pickle_buffer, pickle_length); -}); - -OutboundGroupSession.prototype['unpickle'] = restore_stack(function(key, pickle) { - var key_array = array_from_string(key); - var key_buffer = stack(key_array); - var pickle_array = array_from_string(pickle); - var pickle_buffer = stack(pickle_array); - try { - outbound_group_session_method(Module['_olm_unpickle_outbound_group_session'])( - this.ptr, key_buffer, key_array.length, pickle_buffer, - pickle_array.length - ); - } finally { - // clear out copies of the pickle key - bzero(key_buffer, key_array.length) - for (var i = 0; i < key_array.length; i++) { - key_array[i] = 0; - } - } -}); - -OutboundGroupSession.prototype['create'] = restore_stack(function() { - var random_length = outbound_group_session_method( - Module['_olm_init_outbound_group_session_random_length'] - )(this.ptr); - var random = random_stack(random_length); - outbound_group_session_method(Module['_olm_init_outbound_group_session'])( - this.ptr, random, random_length - ); -}); - -OutboundGroupSession.prototype['encrypt'] = function(plaintext) { - var plaintext_buffer, message_buffer, plaintext_length; - try { - plaintext_length = lengthBytesUTF8(plaintext); - - var message_length = outbound_group_session_method( - Module['_olm_group_encrypt_message_length'] - )(this.ptr, plaintext_length); - - // need to allow space for the terminator (which stringToUTF8 always - // writes), hence + 1. - plaintext_buffer = malloc(plaintext_length + 1); - stringToUTF8(plaintext, plaintext_buffer, plaintext_length + 1); - - message_buffer = malloc(message_length + NULL_BYTE_PADDING_LENGTH); - outbound_group_session_method(Module['_olm_group_encrypt'])( - this.ptr, - plaintext_buffer, plaintext_length, - message_buffer, message_length - ); - - // UTF8ToString requires a null-terminated argument, so add the - // null terminator. - setValue( - message_buffer+message_length, - 0, "i8" - ); - - return UTF8ToString(message_buffer, message_length); - } finally { - if (plaintext_buffer !== undefined) { - // don't leave a copy of the plaintext in the heap. - bzero(plaintext_buffer, plaintext_length + 1); - free(plaintext_buffer); - } - if (message_buffer !== undefined) { - free(message_buffer); - } - } -}; - -OutboundGroupSession.prototype['session_id'] = restore_stack(function() { - var length = outbound_group_session_method( - Module['_olm_outbound_group_session_id_length'] - )(this.ptr); - var session_id = stack(length + NULL_BYTE_PADDING_LENGTH); - outbound_group_session_method(Module['_olm_outbound_group_session_id'])( - this.ptr, session_id, length - ); - return UTF8ToString(session_id, length); -}); - -OutboundGroupSession.prototype['session_key'] = restore_stack(function() { - var key_length = outbound_group_session_method( - Module['_olm_outbound_group_session_key_length'] - )(this.ptr); - var key = stack(key_length + NULL_BYTE_PADDING_LENGTH); - outbound_group_session_method(Module['_olm_outbound_group_session_key'])( - this.ptr, key, key_length - ); - var key_str = UTF8ToString(key, key_length); - bzero(key, key_length); // clear out our copy of the key - return key_str; -}); - -OutboundGroupSession.prototype['message_index'] = function() { - var idx = outbound_group_session_method( - Module['_olm_outbound_group_session_message_index'] - )(this.ptr); - return idx; -}; - -olm_exports['OutboundGroupSession'] = OutboundGroupSession; diff --git a/javascript/olm_pk.js b/javascript/olm_pk.js deleted file mode 100644 index 4690b90..0000000 --- a/javascript/olm_pk.js +++ /dev/null @@ -1,362 +0,0 @@ -function PkEncryption() { - var size = Module['_olm_pk_encryption_size'](); - this.buf = malloc(size); - this.ptr = Module['_olm_pk_encryption'](this.buf); -} - -function pk_encryption_method(wrapped) { - return function() { - var result = wrapped.apply(this, arguments); - if (result === OLM_ERROR) { - var message = UTF8ToString( - Module['_olm_pk_encryption_last_error'](arguments[0]) - ); - throw new Error("OLM." + message); - } - return result; - } -} - -PkEncryption.prototype['free'] = function() { - Module['_olm_clear_pk_encryption'](this.ptr); - free(this.ptr); -} - -PkEncryption.prototype['set_recipient_key'] = restore_stack(function(key) { - var key_array = array_from_string(key); - var key_buffer = stack(key_array); - pk_encryption_method(Module['_olm_pk_encryption_set_recipient_key'])( - this.ptr, key_buffer, key_array.length - ); -}); - -PkEncryption.prototype['encrypt'] = restore_stack(function( - plaintext -) { - var plaintext_buffer, ciphertext_buffer, plaintext_length, random, random_length; - try { - plaintext_length = lengthBytesUTF8(plaintext) - plaintext_buffer = malloc(plaintext_length + 1); - stringToUTF8(plaintext, plaintext_buffer, plaintext_length + 1); - random_length = pk_encryption_method( - Module['_olm_pk_encrypt_random_length'] - )(); - random = random_stack(random_length); - var ciphertext_length = pk_encryption_method( - Module['_olm_pk_ciphertext_length'] - )(this.ptr, plaintext_length); - ciphertext_buffer = malloc(ciphertext_length + NULL_BYTE_PADDING_LENGTH); - var mac_length = pk_encryption_method( - Module['_olm_pk_mac_length'] - )(this.ptr); - var mac_buffer = stack(mac_length + NULL_BYTE_PADDING_LENGTH); - setValue( - mac_buffer + mac_length, - 0, "i8" - ); - var ephemeral_length = pk_encryption_method( - Module['_olm_pk_key_length'] - )(); - var ephemeral_buffer = stack(ephemeral_length + NULL_BYTE_PADDING_LENGTH); - setValue( - ephemeral_buffer + ephemeral_length, - 0, "i8" - ); - pk_encryption_method(Module['_olm_pk_encrypt'])( - this.ptr, - plaintext_buffer, plaintext_length, - ciphertext_buffer, ciphertext_length, - mac_buffer, mac_length, - ephemeral_buffer, ephemeral_length, - random, random_length - ); - // UTF8ToString requires a null-terminated argument, so add the - // null terminator. - setValue( - ciphertext_buffer + ciphertext_length, - 0, "i8" - ); - return { - "ciphertext": UTF8ToString(ciphertext_buffer, ciphertext_length), - "mac": UTF8ToString(mac_buffer, mac_length), - "ephemeral": UTF8ToString(ephemeral_buffer, ephemeral_length) - }; - } finally { - if (random !== undefined) { - // clear out the random buffer, since it is key data - bzero(random, random_length); - } - if (plaintext_buffer !== undefined) { - // don't leave a copy of the plaintext in the heap. - bzero(plaintext_buffer, plaintext_length + 1); - free(plaintext_buffer); - } - if (ciphertext_buffer !== undefined) { - free(ciphertext_buffer); - } - } -}); - - -function PkDecryption() { - var size = Module['_olm_pk_decryption_size'](); - this.buf = malloc(size); - this.ptr = Module['_olm_pk_decryption'](this.buf); -} - -function pk_decryption_method(wrapped) { - return function() { - var result = wrapped.apply(this, arguments); - if (result === OLM_ERROR) { - var message = UTF8ToString( - Module['_olm_pk_decryption_last_error'](arguments[0]) - ); - throw new Error("OLM." + message); - } - return result; - } -} - -PkDecryption.prototype['free'] = function() { - Module['_olm_clear_pk_decryption'](this.ptr); - free(this.ptr); -} - -PkDecryption.prototype['init_with_private_key'] = restore_stack(function (private_key) { - var private_key_buffer = stack(private_key.length); - Module['HEAPU8'].set(private_key, private_key_buffer); - - var pubkey_length = pk_decryption_method( - Module['_olm_pk_key_length'] - )(); - var pubkey_buffer = stack(pubkey_length + NULL_BYTE_PADDING_LENGTH); - try { - pk_decryption_method(Module['_olm_pk_key_from_private'])( - this.ptr, - pubkey_buffer, pubkey_length, - private_key_buffer, private_key.length - ); - } finally { - // clear out our copy of the private key - bzero(private_key_buffer, private_key.length); - } - return UTF8ToString(pubkey_buffer, pubkey_length); -}); - -PkDecryption.prototype['generate_key'] = restore_stack(function () { - var random_length = pk_decryption_method( - Module['_olm_pk_private_key_length'] - )(); - var random_buffer = random_stack(random_length); - var pubkey_length = pk_decryption_method( - Module['_olm_pk_key_length'] - )(); - var pubkey_buffer = stack(pubkey_length + NULL_BYTE_PADDING_LENGTH); - try { - pk_decryption_method(Module['_olm_pk_key_from_private'])( - this.ptr, - pubkey_buffer, pubkey_length, - random_buffer, random_length - ); - } finally { - // clear out the random buffer (= private key) - bzero(random_buffer, random_length); - } - return UTF8ToString(pubkey_buffer, pubkey_length); -}); - -PkDecryption.prototype['get_private_key'] = restore_stack(function () { - var privkey_length = pk_encryption_method( - Module['_olm_pk_private_key_length'] - )(); - var privkey_buffer = stack(privkey_length); - pk_decryption_method(Module['_olm_pk_get_private_key'])( - this.ptr, - privkey_buffer, privkey_length - ); - // The inner Uint8Array creates a view of the buffer. The outer Uint8Array - // copies it to a new array to return, since the original buffer will get - // deallocated from the stack and could get overwritten. - var key_arr = new Uint8Array( - new Uint8Array(Module['HEAPU8'].buffer, privkey_buffer, privkey_length) - ); - bzero(privkey_buffer, privkey_length); // clear out our copy of the key - return key_arr; -}); - -PkDecryption.prototype['pickle'] = restore_stack(function (key) { - var key_array = array_from_string(key); - var pickle_length = pk_decryption_method( - Module['_olm_pickle_pk_decryption_length'] - )(this.ptr); - var key_buffer = stack(key_array); - var pickle_buffer = stack(pickle_length + NULL_BYTE_PADDING_LENGTH); - try { - pk_decryption_method(Module['_olm_pickle_pk_decryption'])( - this.ptr, key_buffer, key_array.length, pickle_buffer, pickle_length - ); - } finally { - // clear out copies of the pickle key - bzero(key_buffer, key_array.length) - for (var i = 0; i < key_array.length; i++) { - key_array[i] = 0; - } - } - return UTF8ToString(pickle_buffer, pickle_length); -}); - -PkDecryption.prototype['unpickle'] = restore_stack(function (key, pickle) { - var key_array = array_from_string(key); - var key_buffer = stack(key_array); - var pickle_array = array_from_string(pickle); - var pickle_buffer = stack(pickle_array); - var ephemeral_length = pk_decryption_method( - Module["_olm_pk_key_length"] - )(); - var ephemeral_buffer = stack(ephemeral_length + NULL_BYTE_PADDING_LENGTH); - try { - pk_decryption_method(Module['_olm_unpickle_pk_decryption'])( - this.ptr, key_buffer, key_array.length, pickle_buffer, - pickle_array.length, ephemeral_buffer, ephemeral_length - ); - } finally { - // clear out copies of the pickle key - bzero(key_buffer, key_array.length) - for (var i = 0; i < key_array.length; i++) { - key_array[i] = 0; - } - } - return UTF8ToString(ephemeral_buffer, ephemeral_length); -}); - -PkDecryption.prototype['decrypt'] = restore_stack(function ( - ephemeral_key, mac, ciphertext -) { - var plaintext_buffer, ciphertext_buffer, plaintext_max_length; - try { - var ciphertext_length = lengthBytesUTF8(ciphertext) - ciphertext_buffer = malloc(ciphertext_length + 1); - stringToUTF8(ciphertext, ciphertext_buffer, ciphertext_length + 1); - var ephemeralkey_array = array_from_string(ephemeral_key); - var ephemeralkey_buffer = stack(ephemeralkey_array); - var mac_array = array_from_string(mac); - var mac_buffer = stack(mac_array); - plaintext_max_length = pk_decryption_method(Module['_olm_pk_max_plaintext_length'])( - this.ptr, - ciphertext_length - ); - plaintext_buffer = malloc(plaintext_max_length + NULL_BYTE_PADDING_LENGTH); - var plaintext_length = pk_decryption_method(Module['_olm_pk_decrypt'])( - this.ptr, - ephemeralkey_buffer, ephemeralkey_array.length, - mac_buffer, mac_array.length, - ciphertext_buffer, ciphertext_length, - plaintext_buffer, plaintext_max_length - ); - // UTF8ToString requires a null-terminated argument, so add the - // null terminator. - setValue( - plaintext_buffer + plaintext_length, - 0, "i8" - ); - return UTF8ToString(plaintext_buffer, plaintext_length); - } finally { - if (plaintext_buffer !== undefined) { - // don't leave a copy of the plaintext in the heap. - bzero(plaintext_buffer, plaintext_length + 1); - free(plaintext_buffer); - } - if (ciphertext_buffer !== undefined) { - free(ciphertext_buffer); - } - } -}) - - -function PkSigning() { - var size = Module['_olm_pk_signing_size'](); - this.buf = malloc(size); - this.ptr = Module['_olm_pk_signing'](this.buf); -} - -function pk_signing_method(wrapped) { - return function() { - var result = wrapped.apply(this, arguments); - if (result === OLM_ERROR) { - var message = UTF8ToString( - Module['_olm_pk_signing_last_error'](arguments[0]) - ); - throw new Error("OLM." + message); - } - return result; - } -} - -PkSigning.prototype['free'] = function() { - Module['_olm_clear_pk_signing'](this.ptr); - free(this.ptr); -} - -PkSigning.prototype['init_with_seed'] = restore_stack(function (seed) { - var seed_buffer = stack(seed.length); - Module['HEAPU8'].set(seed, seed_buffer); - - var pubkey_length = pk_signing_method( - Module['_olm_pk_signing_public_key_length'] - )(); - var pubkey_buffer = stack(pubkey_length + NULL_BYTE_PADDING_LENGTH); - try { - pk_signing_method(Module['_olm_pk_signing_key_from_seed'])( - this.ptr, - pubkey_buffer, pubkey_length, - seed_buffer, seed.length - ); - } finally { - // clear out our copy of the seed - bzero(seed_buffer, seed.length); - } - return UTF8ToString(pubkey_buffer, pubkey_length); -}); - -PkSigning.prototype['generate_seed'] = restore_stack(function () { - var random_length = pk_signing_method( - Module['_olm_pk_signing_seed_length'] - )(); - var random_buffer = random_stack(random_length); - var key_arr = new Uint8Array( - new Uint8Array(Module['HEAPU8'].buffer, random_buffer, random_length) - ); - bzero(random_buffer, random_length); - return key_arr; -}); - -PkSigning.prototype['sign'] = restore_stack(function (message) { - // XXX: Should be able to sign any bytes rather than just strings, - // but this is consistent with encrypt for now. - //var message_buffer = stack(message.length); - //Module['HEAPU8'].set(message, message_buffer); - var message_buffer, message_length; - - try { - message_length = lengthBytesUTF8(message) - message_buffer = malloc(message_length + 1); - stringToUTF8(message, message_buffer, message_length + 1); - - var sig_length = pk_signing_method( - Module['_olm_pk_signature_length'] - )(); - var sig_buffer = stack(sig_length + NULL_BYTE_PADDING_LENGTH); - pk_signing_method(Module['_olm_pk_sign'])( - this.ptr, - message_buffer, message_length, - sig_buffer, sig_length - ); - return UTF8ToString(sig_buffer, sig_length); - } finally { - if (message_buffer !== undefined) { - // don't leave a copy of the plaintext in the heap. - bzero(message_buffer, message_length + 1); - free(message_buffer); - } - } -}); diff --git a/javascript/olm_post.js b/javascript/olm_post.js deleted file mode 100644 index 450861a..0000000 --- a/javascript/olm_post.js +++ /dev/null @@ -1,587 +0,0 @@ -var malloc = Module['_malloc']; -var free = Module['_free']; -var OLM_ERROR; - -function filled_stack(size, filler) { - var ptr = stackAlloc(size); - filler(new Uint8Array(Module['HEAPU8'].buffer, ptr, size)); - return ptr; -} - -/* allocate a number of bytes of storage on the stack. - * - * If size_or_array is a Number, allocates that number of zero-initialised bytes. - */ -function stack(size_or_array) { - return (typeof size_or_array == 'number') - ? filled_stack(size_or_array, function(x) { x.fill(0) }) - : filled_stack(size_or_array.length, function(x) { x.set(size_or_array) }); -} - -function array_from_string(string) { - return string instanceof Uint8Array ? string : intArrayFromString(string, true); -} - -function random_stack(size) { - return filled_stack(size, get_random_values); -} - -function restore_stack(wrapped) { - return function() { - var sp = stackSave(); - try { - return wrapped.apply(this, arguments); - } finally { - stackRestore(sp); - } - } -} - -/* set a memory area to zero */ -function bzero(ptr, n) { - while(n-- > 0) { - Module['HEAP8'][ptr++] = 0; - } -} - -function Account() { - var size = Module['_olm_account_size'](); - this.buf = malloc(size); - this.ptr = Module['_olm_account'](this.buf); -} - -function account_method(wrapped) { - return function() { - var result = wrapped.apply(this, arguments); - if (result === OLM_ERROR) { - var message = UTF8ToString( - Module['_olm_account_last_error'](arguments[0]) - ); - throw new Error("OLM." + message); - } - return result; - } -} - -Account.prototype['free'] = function() { - Module['_olm_clear_account'](this.ptr); - free(this.ptr); -} - -Account.prototype['create'] = restore_stack(function() { - var random_length = account_method( - Module['_olm_create_account_random_length'] - )(this.ptr); - var random = random_stack(random_length); - account_method(Module['_olm_create_account'])( - this.ptr, random, random_length - ); -}); - -Account.prototype['identity_keys'] = restore_stack(function() { - var keys_length = account_method( - Module['_olm_account_identity_keys_length'] - )(this.ptr); - var keys = stack(keys_length + NULL_BYTE_PADDING_LENGTH); - account_method(Module['_olm_account_identity_keys'])( - this.ptr, keys, keys_length - ); - return UTF8ToString(keys, keys_length); -}); - -Account.prototype['sign'] = restore_stack(function(message) { - var signature_length = account_method( - Module['_olm_account_signature_length'] - )(this.ptr); - var message_array = array_from_string(message); - var message_buffer = stack(message_array); - var signature_buffer = stack(signature_length + NULL_BYTE_PADDING_LENGTH); - try { - account_method(Module['_olm_account_sign'])( - this.ptr, - message_buffer, message_array.length, - signature_buffer, signature_length - ); - } finally { - // clear out copies of the message, which may be plaintext - bzero(message_buffer, message_array.length); - for (var i = 0; i < message_array.length; i++) { - message_array[i] = 0; - } - } - return UTF8ToString(signature_buffer, signature_length); -}); - -Account.prototype['one_time_keys'] = restore_stack(function() { - var keys_length = account_method( - Module['_olm_account_one_time_keys_length'] - )(this.ptr); - var keys = stack(keys_length + NULL_BYTE_PADDING_LENGTH); - account_method(Module['_olm_account_one_time_keys'])( - this.ptr, keys, keys_length - ); - return UTF8ToString(keys, keys_length); -}); - -Account.prototype['mark_keys_as_published'] = restore_stack(function() { - account_method(Module['_olm_account_mark_keys_as_published'])(this.ptr); -}); - -Account.prototype['max_number_of_one_time_keys'] = restore_stack(function() { - return account_method(Module['_olm_account_max_number_of_one_time_keys'])( - this.ptr - ); -}); - -Account.prototype['generate_one_time_keys'] = restore_stack(function( - number_of_keys -) { - var random_length = account_method( - Module['_olm_account_generate_one_time_keys_random_length'] - )(this.ptr, number_of_keys); - var random = random_stack(random_length); - account_method(Module['_olm_account_generate_one_time_keys'])( - this.ptr, number_of_keys, random, random_length - ); -}); - -Account.prototype['remove_one_time_keys'] = restore_stack(function(session) { - account_method(Module['_olm_remove_one_time_keys'])( - this.ptr, session.ptr - ); -}); - -Account.prototype['generate_fallback_key'] = restore_stack(function() { - var random_length = account_method( - Module['_olm_account_generate_fallback_key_random_length'] - )(this.ptr); - var random = random_stack(random_length); - account_method(Module['_olm_account_generate_fallback_key'])( - this.ptr, random, random_length - ); -}); - -Account.prototype['fallback_key'] = restore_stack(function() { - var keys_length = account_method( - Module['_olm_account_fallback_key_length'] - )(this.ptr); - var keys = stack(keys_length + NULL_BYTE_PADDING_LENGTH); - account_method(Module['_olm_account_fallback_key'])( - this.ptr, keys, keys_length - ); - return UTF8ToString(keys, keys_length); -}); - -Account.prototype['pickle'] = restore_stack(function(key) { - var key_array = array_from_string(key); - var pickle_length = account_method( - Module['_olm_pickle_account_length'] - )(this.ptr); - var key_buffer = stack(key_array); - var pickle_buffer = stack(pickle_length + NULL_BYTE_PADDING_LENGTH); - try { - account_method(Module['_olm_pickle_account'])( - this.ptr, key_buffer, key_array.length, pickle_buffer, pickle_length - ); - } finally { - // clear out copies of the pickle key - bzero(key_buffer, key_array.length) - for (var i = 0; i < key_array.length; i++) { - key_array[i] = 0; - } - } - return UTF8ToString(pickle_buffer, pickle_length); -}); - -Account.prototype['unpickle'] = restore_stack(function(key, pickle) { - var key_array = array_from_string(key); - var key_buffer = stack(key_array); - var pickle_array = array_from_string(pickle); - var pickle_buffer = stack(pickle_array); - try { - account_method(Module['_olm_unpickle_account'])( - this.ptr, key_buffer, key_array.length, pickle_buffer, - pickle_array.length - ); - } finally { - // clear out copies of the pickle key - bzero(key_buffer, key_array.length) - for (var i = 0; i < key_array.length; i++) { - key_array[i] = 0; - } - } -}); - -function Session() { - var size = Module['_olm_session_size'](); - this.buf = malloc(size); - this.ptr = Module['_olm_session'](this.buf); -} - -function session_method(wrapped) { - return function() { - var result = wrapped.apply(this, arguments); - if (result === OLM_ERROR) { - var message = UTF8ToString( - Module['_olm_session_last_error'](arguments[0]) - ); - throw new Error("OLM." + message); - } - return result; - } -} - -Session.prototype['free'] = function() { - Module['_olm_clear_session'](this.ptr); - free(this.ptr); -} - -Session.prototype['pickle'] = restore_stack(function(key) { - var key_array = array_from_string(key); - var pickle_length = session_method( - Module['_olm_pickle_session_length'] - )(this.ptr); - var key_buffer = stack(key_array); - var pickle_buffer = stack(pickle_length + NULL_BYTE_PADDING_LENGTH); - try { - session_method(Module['_olm_pickle_session'])( - this.ptr, key_buffer, key_array.length, pickle_buffer, pickle_length - ); - } finally { - // clear out copies of the pickle key - bzero(key_buffer, key_array.length) - for (var i = 0; i < key_array.length; i++) { - key_array[i] = 0; - } - } - return UTF8ToString(pickle_buffer, pickle_length); -}); - -Session.prototype['unpickle'] = restore_stack(function(key, pickle) { - var key_array = array_from_string(key); - var key_buffer = stack(key_array); - var pickle_array = array_from_string(pickle); - var pickle_buffer = stack(pickle_array); - try { - session_method(Module['_olm_unpickle_session'])( - this.ptr, key_buffer, key_array.length, pickle_buffer, - pickle_array.length - ); - } finally { - // clear out copies of the pickle key - bzero(key_buffer, key_array.length) - for (var i = 0; i < key_array.length; i++) { - key_array[i] = 0; - } - } -}); - -Session.prototype['create_outbound'] = restore_stack(function( - account, their_identity_key, their_one_time_key -) { - var random_length = session_method( - Module['_olm_create_outbound_session_random_length'] - )(this.ptr); - var random = random_stack(random_length); - var identity_key_array = array_from_string(their_identity_key); - var one_time_key_array = array_from_string(their_one_time_key); - var identity_key_buffer = stack(identity_key_array); - var one_time_key_buffer = stack(one_time_key_array); - try { - session_method(Module['_olm_create_outbound_session'])( - this.ptr, account.ptr, - identity_key_buffer, identity_key_array.length, - one_time_key_buffer, one_time_key_array.length, - random, random_length - ); - } finally { - // clear the random buffer, which is key data - bzero(random, random_length); - } -}); - -Session.prototype['create_inbound'] = restore_stack(function( - account, one_time_key_message -) { - var message_array = array_from_string(one_time_key_message); - var message_buffer = stack(message_array); - try { - session_method(Module['_olm_create_inbound_session'])( - this.ptr, account.ptr, message_buffer, message_array.length - ); - } finally { - // clear out copies of the key - bzero(message_buffer, message_array.length); - for (var i = 0; i < message_array.length; i++) { - message_array[i] = 0; - } - } -}); - -Session.prototype['create_inbound_from'] = restore_stack(function( - account, identity_key, one_time_key_message -) { - var identity_key_array = array_from_string(identity_key); - var identity_key_buffer = stack(identity_key_array); - var message_array = array_from_string(one_time_key_message); - var message_buffer = stack(message_array); - try { - session_method(Module['_olm_create_inbound_session_from'])( - this.ptr, account.ptr, - identity_key_buffer, identity_key_array.length, - message_buffer, message_array.length - ); - } finally { - // clear out copies of the key - bzero(message_buffer, message_array.length); - for (var i = 0; i < message_array.length; i++) { - message_array[i] = 0; - } - } -}); - -Session.prototype['session_id'] = restore_stack(function() { - var id_length = session_method(Module['_olm_session_id_length'])(this.ptr); - var id_buffer = stack(id_length + NULL_BYTE_PADDING_LENGTH); - session_method(Module['_olm_session_id'])( - this.ptr, id_buffer, id_length - ); - return UTF8ToString(id_buffer, id_length); -}); - -Session.prototype['has_received_message'] = function() { - return session_method(Module['_olm_session_has_received_message'])( - this.ptr - ) ? true : false; -}; - - -Session.prototype['matches_inbound'] = restore_stack(function( - one_time_key_message -) { - var message_array = array_from_string(one_time_key_message); - var message_buffer = stack(message_array); - return session_method(Module['_olm_matches_inbound_session'])( - this.ptr, message_buffer, message_array.length - ) ? true : false; -}); - -Session.prototype['matches_inbound_from'] = restore_stack(function( - identity_key, one_time_key_message -) { - var identity_key_array = array_from_string(identity_key); - var identity_key_buffer = stack(identity_key_array); - var message_array = array_from_string(one_time_key_message); - var message_buffer = stack(message_array); - return session_method(Module['_olm_matches_inbound_session_from'])( - this.ptr, - identity_key_buffer, identity_key_array.length, - message_buffer, message_array.length - ) ? true : false; -}); - -Session.prototype['encrypt'] = restore_stack(function( - plaintext -) { - var plaintext_buffer, message_buffer, plaintext_length, random, random_length; - try { - random_length = session_method( - Module['_olm_encrypt_random_length'] - )(this.ptr); - var message_type = session_method( - Module['_olm_encrypt_message_type'] - )(this.ptr); - - plaintext_length = lengthBytesUTF8(plaintext); - var message_length = session_method( - Module['_olm_encrypt_message_length'] - )(this.ptr, plaintext_length); - - random = random_stack(random_length); - - // need to allow space for the terminator (which stringToUTF8 always - // writes), hence + 1. - plaintext_buffer = malloc(plaintext_length + 1); - stringToUTF8(plaintext, plaintext_buffer, plaintext_length + 1); - - message_buffer = malloc(message_length + NULL_BYTE_PADDING_LENGTH); - - session_method(Module['_olm_encrypt'])( - this.ptr, - plaintext_buffer, plaintext_length, - random, random_length, - message_buffer, message_length - ); - - // UTF8ToString requires a null-terminated argument, so add the - // null terminator. - setValue( - message_buffer+message_length, - 0, "i8" - ); - - return { - "type": message_type, - "body": UTF8ToString(message_buffer, message_length), - }; - } finally { - if (random !== undefined) { - // clear out the random buffer, since it is the private key - bzero(random, random_length); - } - if (plaintext_buffer !== undefined) { - // don't leave a copy of the plaintext in the heap. - bzero(plaintext_buffer, plaintext_length + 1); - free(plaintext_buffer); - } - if (message_buffer !== undefined) { - free(message_buffer); - } - } -}); - -Session.prototype['decrypt'] = restore_stack(function( - message_type, message -) { - var message_buffer, plaintext_buffer, max_plaintext_length; - - try { - message_buffer = malloc(message.length); - writeAsciiToMemory(message, message_buffer, true); - - max_plaintext_length = session_method( - Module['_olm_decrypt_max_plaintext_length'] - )(this.ptr, message_type, message_buffer, message.length); - - // caculating the length destroys the input buffer, so we need to re-copy it. - writeAsciiToMemory(message, message_buffer, true); - - plaintext_buffer = malloc(max_plaintext_length + NULL_BYTE_PADDING_LENGTH); - - var plaintext_length = session_method(Module["_olm_decrypt"])( - this.ptr, message_type, - message_buffer, message.length, - plaintext_buffer, max_plaintext_length - ); - - // UTF8ToString requires a null-terminated argument, so add the - // null terminator. - setValue( - plaintext_buffer+plaintext_length, - 0, "i8" - ); - - return UTF8ToString(plaintext_buffer, plaintext_length); - } finally { - if (message_buffer !== undefined) { - free(message_buffer); - } - if (plaintext_buffer !== undefined) { - // don't leave a copy of the plaintext in the heap. - bzero(plaintext_buffer, max_plaintext_length); - free(plaintext_buffer); - } - } - -}); - -Session.prototype['describe'] = restore_stack(function() { - var description_buf; - try { - description_buf = malloc(256); - session_method(Module['_olm_session_describe'])( - this.ptr, description_buf, 256 - ); - return UTF8ToString(description_buf); - } finally { - if (description_buf !== undefined) free(description_buf); - } -}); - -function Utility() { - var size = Module['_olm_utility_size'](); - this.buf = malloc(size); - this.ptr = Module['_olm_utility'](this.buf); -} - -function utility_method(wrapped) { - return function() { - var result = wrapped.apply(this, arguments); - if (result === OLM_ERROR) { - var message = UTF8ToString( - Module['_olm_utility_last_error'](arguments[0]) - ); - throw new Error("OLM." + message); - } - return result; - } -} - -Utility.prototype['free'] = function() { - Module['_olm_clear_utility'](this.ptr); - free(this.ptr); -} - -Utility.prototype['sha256'] = restore_stack(function(input) { - var output_length = utility_method(Module['_olm_sha256_length'])(this.ptr); - var input_array = array_from_string(input); - var input_buffer = stack(input_array); - var output_buffer = stack(output_length + NULL_BYTE_PADDING_LENGTH); - try { - utility_method(Module['_olm_sha256'])( - this.ptr, - input_buffer, input_array.length, - output_buffer, output_length - ); - } finally { - // clear out copies of the input buffer, which may be plaintext - bzero(input_buffer, input_array.length); - for (var i = 0; i < input_array.length; i++) { - input_array[i] = 0; - } - } - return UTF8ToString(output_buffer, output_length); -}); - -Utility.prototype['ed25519_verify'] = restore_stack(function( - key, message, signature -) { - var key_array = array_from_string(key); - var key_buffer = stack(key_array); - var message_array = array_from_string(message); - var message_buffer = stack(message_array); - var signature_array = array_from_string(signature); - var signature_buffer = stack(signature_array); - try { - utility_method(Module['_olm_ed25519_verify'])( - this.ptr, - key_buffer, key_array.length, - message_buffer, message_array.length, - signature_buffer, signature_array.length - ); - } finally { - // clear out copies of the input buffer, which may be plaintext - bzero(message_buffer, message_array.length); - for (var i = 0; i < message_array.length; i++) { - message_array[i] = 0; - } - } -}); - -olm_exports["Account"] = Account; -olm_exports["Session"] = Session; -olm_exports["Utility"] = Utility; -olm_exports["PkEncryption"] = PkEncryption; -olm_exports["PkDecryption"] = PkDecryption; -olm_exports["PkSigning"] = PkSigning; -olm_exports["SAS"] = SAS; - -olm_exports["get_library_version"] = restore_stack(function() { - var buf = stack(3); - Module['_olm_get_library_version'](buf, buf+1, buf+2); - return [ - getValue(buf, 'i8'), - getValue(buf+1, 'i8'), - getValue(buf+2, 'i8'), - ]; -}); diff --git a/javascript/olm_pre.js b/javascript/olm_pre.js deleted file mode 100644 index 314d7da..0000000 --- a/javascript/olm_pre.js +++ /dev/null @@ -1,49 +0,0 @@ -var get_random_values; - -if (typeof(window) !== 'undefined') { - // We're in a browser (directly, via browserify, or via webpack). - get_random_values = function(buf) { - window.crypto.getRandomValues(buf); - }; -} else if (module["exports"]) { - // We're running in node. - var nodeCrypto = require("crypto"); - get_random_values = function(buf) { - // [''] syntax needed here rather than '.' to prevent - // closure compiler from mangling the import(!) - var bytes = nodeCrypto['randomBytes'](buf.length); - buf.set(bytes); - }; - process = global["process"]; -} else { - throw new Error("Cannot find global to attach library to"); -} - -/* applications should define OLM_OPTIONS in the environment to override - * emscripten module settings - */ -if (typeof(OLM_OPTIONS) !== 'undefined') { - for (var olm_option_key in OLM_OPTIONS) { - if (OLM_OPTIONS.hasOwnProperty(olm_option_key)) { - Module[olm_option_key] = OLM_OPTIONS[olm_option_key]; - } - } -} - -/* The 'length' argument to Pointer_stringify doesn't work if the input - * includes characters >= 128, which makes Pointer_stringify unreliable. We - * could use it on strings which are known to be ascii, but that seems - * dangerous. Instead we add a NULL character to all of our strings and just - * use UTF8ToString. - */ -var NULL_BYTE_PADDING_LENGTH = 1; - -Module['onRuntimeInitialized'] = function() { - OLM_ERROR = Module['_olm_error'](); - olm_exports["PRIVATE_KEY_LENGTH"] = Module['_olm_pk_private_key_length'](); - if (onInitSuccess) onInitSuccess(); -}; - -Module['onAbort'] = function(err) { - if (onInitFail) onInitFail(err); -}; diff --git a/javascript/olm_prefix.js b/javascript/olm_prefix.js deleted file mode 100644 index ae2d9f9..0000000 --- a/javascript/olm_prefix.js +++ /dev/null @@ -1,4 +0,0 @@ -var Olm = (function() { -var olm_exports = {}; -var onInitSuccess; -var onInitFail; diff --git a/javascript/olm_sas.js b/javascript/olm_sas.js deleted file mode 100644 index 38535d5..0000000 --- a/javascript/olm_sas.js +++ /dev/null @@ -1,99 +0,0 @@ -function SAS() { - var size = Module['_olm_sas_size'](); - var random_length = Module['_olm_create_sas_random_length'](); - var random = random_stack(random_length); - this.buf = malloc(size); - this.ptr = Module['_olm_sas'](this.buf); - Module['_olm_create_sas'](this.ptr, random, random_length); - bzero(random, random_length); -} - -function sas_method(wrapped) { - return function() { - var result = wrapped.apply(this, arguments); - if (result === OLM_ERROR) { - var message = UTF8ToString( - Module['_olm_sas_last_error'](arguments[0]) - ); - throw new Error("OLM." + message); - } - return result; - } -} - -SAS.prototype['free'] = function() { - Module['_olm_clear_sas'](this.ptr); - free(this.ptr); -}; - -SAS.prototype['get_pubkey'] = restore_stack(function() { - var pubkey_length = sas_method(Module['_olm_sas_pubkey_length'])(this.ptr); - var pubkey_buffer = stack(pubkey_length + NULL_BYTE_PADDING_LENGTH); - sas_method(Module['_olm_sas_get_pubkey'])(this.ptr, pubkey_buffer, pubkey_length); - return UTF8ToString(pubkey_buffer, pubkey_length); -}); - -SAS.prototype['set_their_key'] = restore_stack(function(their_key) { - var their_key_array = array_from_string(their_key); - var their_key_buffer = stack(their_key_array); - sas_method(Module['_olm_sas_set_their_key'])( - this.ptr, - their_key_buffer, their_key_array.length - ); -}); - -SAS.prototype['is_their_key_set'] = restore_stack(function() { - return sas_method(Module['_olm_sas_is_their_key_set'])( - this.ptr - ) ? true : false; -}); - -SAS.prototype['generate_bytes'] = restore_stack(function(info, length) { - var info_array = array_from_string(info); - var info_buffer = stack(info_array); - var output_buffer = stack(length); - sas_method(Module['_olm_sas_generate_bytes'])( - this.ptr, - info_buffer, info_array.length, - output_buffer, length - ); - // The inner Uint8Array creates a view of the buffer. The outer Uint8Array - // copies it to a new array to return, since the original buffer will get - // deallocated from the stack and could get overwritten. - var output_arr = new Uint8Array( - new Uint8Array(Module['HEAPU8'].buffer, output_buffer, length) - ); - return output_arr; -}); - -SAS.prototype['calculate_mac'] = restore_stack(function(input, info) { - var input_array = array_from_string(input); - var input_buffer = stack(input_array); - var info_array = array_from_string(info); - var info_buffer = stack(info_array); - var mac_length = sas_method(Module['_olm_sas_mac_length'])(this.ptr); - var mac_buffer = stack(mac_length + NULL_BYTE_PADDING_LENGTH); - sas_method(Module['_olm_sas_calculate_mac'])( - this.ptr, - input_buffer, input_array.length, - info_buffer, info_array.length, - mac_buffer, mac_length - ); - return UTF8ToString(mac_buffer, mac_length); -}); - -SAS.prototype['calculate_mac_long_kdf'] = restore_stack(function(input, info) { - var input_array = array_from_string(input); - var input_buffer = stack(input_array); - var info_array = array_from_string(info); - var info_buffer = stack(info_array); - var mac_length = sas_method(Module['_olm_sas_mac_length'])(this.ptr); - var mac_buffer = stack(mac_length + NULL_BYTE_PADDING_LENGTH); - sas_method(Module['_olm_sas_calculate_mac_long_kdf'])( - this.ptr, - input_buffer, input_array.length, - info_buffer, info_array.length, - mac_buffer, mac_length - ); - return UTF8ToString(mac_buffer, mac_length); -}); diff --git a/javascript/olm_suffix.js b/javascript/olm_suffix.js deleted file mode 100644 index d6f72b7..0000000 --- a/javascript/olm_suffix.js +++ /dev/null @@ -1,36 +0,0 @@ -var olmInitPromise; - -olm_exports['init'] = function(opts) { - if (olmInitPromise) return olmInitPromise; - - if (opts) OLM_OPTIONS = opts; - - olmInitPromise = new Promise(function(resolve, reject) { - onInitSuccess = function() { - resolve(); - }; - onInitFail = function(err) { - reject(err); - }; - Module(); - }); - return olmInitPromise; -}; - -return olm_exports; - -})(); - -if (typeof(window) !== 'undefined') { - // We've been imported directly into a browser. Define the global 'Olm' object. - // (we do this even if module.exports was defined, because it's useful to have - // Olm in the global scope for browserified and webpacked apps.) - window["Olm"] = Olm; -} - -if (typeof module === 'object') { - // Emscripten sets the module exports to be its module - // with wrapped c functions. Clobber it with our higher - // level wrapper class. - module.exports = Olm; -} diff --git a/javascript/package.json b/javascript/package.json deleted file mode 100644 index c479a98..0000000 --- a/javascript/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "olm", - "version": "3.2.1", - "description": "An implementation of the Double Ratchet cryptographic ratchet", - "main": "olm.js", - "files": [ - "olm.js", - "olm.wasm", - "olm_legacy.js", - "index.d.ts", - "README.md" - ], - "scripts": { - "build": "make -C .. js", - "test": "jasmine-node test --verbose --junitreport --captureExceptions" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/matrix-org/olm.git" - }, - "keywords": [ - "matrix-org" - ], - "author": "matrix.org", - "license": "Apache-2.0", - "bugs": { - "url": "https://github.com/matrix-org/olm/issues" - }, - "homepage": "https://github.com/matrix-org/olm#readme", - "devDependencies": { - "jasmine-node": "^1.14.5" - } -} diff --git a/javascript/test/megolm.spec.js b/javascript/test/megolm.spec.js deleted file mode 100644 index 241d4bd..0000000 --- a/javascript/test/megolm.spec.js +++ /dev/null @@ -1,73 +0,0 @@ -/* -Copyright 2016 OpenMarket Ltd -Copyright 2018 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. -*/ - -"use strict"; - -var Olm = require('../olm'); - -describe("megolm", function() { - var aliceSession, bobSession; - - beforeEach(function(done) { - Olm.init().then(function() { - aliceSession = new Olm.OutboundGroupSession(); - bobSession = new Olm.InboundGroupSession(); - - done(); - }); - }); - - afterEach(function() { - if (aliceSession !== undefined) { - aliceSession.free(); - aliceSession = undefined; - } - - if (bobSession !== undefined) { - bobSession.free(); - bobSession = undefined; - } - }); - - it("should encrypt and decrypt", function() { - aliceSession.create(); - expect(aliceSession.message_index()).toEqual(0); - bobSession.create(aliceSession.session_key()); - - var TEST_TEXT='têst1'; - var encrypted = aliceSession.encrypt(TEST_TEXT); - var decrypted = bobSession.decrypt(encrypted); - console.log(TEST_TEXT, "->", decrypted); - expect(decrypted.plaintext).toEqual(TEST_TEXT); - expect(decrypted.message_index).toEqual(0); - - TEST_TEXT='hot beverage: ☕'; - encrypted = aliceSession.encrypt(TEST_TEXT); - decrypted = bobSession.decrypt(encrypted); - console.log(TEST_TEXT, "->", decrypted); - expect(decrypted.plaintext).toEqual(TEST_TEXT); - expect(decrypted.message_index).toEqual(1); - - // shorter text, to spot buffer overruns - TEST_TEXT='☕'; - encrypted = aliceSession.encrypt(TEST_TEXT); - decrypted = bobSession.decrypt(encrypted); - console.log(TEST_TEXT, "->", decrypted); - expect(decrypted.plaintext).toEqual(TEST_TEXT); - expect(decrypted.message_index).toEqual(2); - }); -}); diff --git a/javascript/test/olm.spec.js b/javascript/test/olm.spec.js deleted file mode 100644 index a698314..0000000 --- a/javascript/test/olm.spec.js +++ /dev/null @@ -1,101 +0,0 @@ -/* -Copyright 2016 OpenMarket Ltd -Copyright 2018 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. -*/ - -"use strict"; - -var Olm = require('../olm'); - -if (!Object.keys) { - Object.keys = function(o) { - var k=[], p; - for (p in o) if (Object.prototype.hasOwnProperty.call(o,p)) k.push(p); - return k; - } -} - -describe("olm", function() { - var aliceAccount, bobAccount; - var aliceSession, bobSession; - - beforeEach(function(done) { - // This should really be in a beforeAll, but jasmine-node - // doesn't support that - Olm.init().then(function() { - aliceAccount = new Olm.Account(); - bobAccount = new Olm.Account(); - aliceSession = new Olm.Session(); - bobSession = new Olm.Session(); - - done(); - }); - }); - - afterEach(function() { - if (aliceAccount !== undefined) { - aliceAccount.free(); - aliceAccount = undefined; - } - - if (bobAccount !== undefined) { - bobAccount.free(); - bobAccount = undefined; - } - - if (aliceSession !== undefined) { - aliceSession.free(); - aliceSession = undefined; - } - - if (bobSession !== undefined) { - bobSession.free(); - bobSession = undefined; - } - }); - - it('should encrypt and decrypt', function() { - aliceAccount.create(); - bobAccount.create(); - - bobAccount.generate_one_time_keys(1); - var bobOneTimeKeys = JSON.parse(bobAccount.one_time_keys()).curve25519; - bobAccount.mark_keys_as_published(); - - var bobIdKey = JSON.parse(bobAccount.identity_keys()).curve25519; - - var otk_id = Object.keys(bobOneTimeKeys)[0]; - - aliceSession.create_outbound( - aliceAccount, bobIdKey, bobOneTimeKeys[otk_id] - ); - - var TEST_TEXT='têst1'; - var encrypted = aliceSession.encrypt(TEST_TEXT); - expect(encrypted.type).toEqual(0); - bobSession.create_inbound(bobAccount, encrypted.body); - bobAccount.remove_one_time_keys(bobSession); - var decrypted = bobSession.decrypt(encrypted.type, encrypted.body); - console.log(TEST_TEXT, "->", decrypted); - expect(decrypted).toEqual(TEST_TEXT); - - TEST_TEXT='hot beverage: ☕'; - encrypted = bobSession.encrypt(TEST_TEXT); - expect(encrypted.type).toEqual(1); - decrypted = aliceSession.decrypt(encrypted.type, encrypted.body); - console.log(TEST_TEXT, "->", decrypted); - expect(decrypted).toEqual(TEST_TEXT); - }); -}); diff --git a/javascript/test/pk.spec.js b/javascript/test/pk.spec.js deleted file mode 100644 index f212b96..0000000 --- a/javascript/test/pk.spec.js +++ /dev/null @@ -1,122 +0,0 @@ -/* -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. -*/ - -"use strict"; - -var Olm = require('../olm'); - -describe("pk", function() { - var encryption, decryption, signing; - - beforeEach(function(done) { - Olm.init().then(function() { - encryption = new Olm.PkEncryption(); - decryption = new Olm.PkDecryption(); - signing = new Olm.PkSigning(); - - done(); - }); - }); - - afterEach(function () { - if (encryption !== undefined) { - encryption.free(); - encryption = undefined; - } - if (decryption !== undefined) { - decryption.free(); - decryption = undefined; - } - if (signing !== undefined) { - signing.free(); - signing = undefined; - } - }); - - it('should import & export keys from private parts', function () { - var alice_private = new Uint8Array([ - 0x77, 0x07, 0x6D, 0x0A, 0x73, 0x18, 0xA5, 0x7D, - 0x3C, 0x16, 0xC1, 0x72, 0x51, 0xB2, 0x66, 0x45, - 0xDF, 0x4C, 0x2F, 0x87, 0xEB, 0xC0, 0x99, 0x2A, - 0xB1, 0x77, 0xFB, 0xA5, 0x1D, 0xB9, 0x2C, 0x2A - ]); - var alice_public = decryption.init_with_private_key(alice_private); - expect(alice_public).toEqual("hSDwCYkwp1R0i33ctD73Wg2/Og0mOBr066SpjqqbTmo"); - - var alice_private_out = decryption.get_private_key(); - expect(alice_private_out).toEqual(alice_private); - }); - - it('should encrypt and decrypt', function () { - var TEST_TEXT='têst1'; - var pubkey = decryption.generate_key(); - encryption.set_recipient_key(pubkey); - var encrypted = encryption.encrypt(TEST_TEXT); - var decrypted = decryption.decrypt(encrypted.ephemeral, encrypted.mac, encrypted.ciphertext); - console.log(TEST_TEXT, "->", decrypted); - expect(decrypted).toEqual(TEST_TEXT); - - TEST_TEXT='hot beverage: ☕'; - encryption.set_recipient_key(pubkey); - encrypted = encryption.encrypt(TEST_TEXT); - decrypted = decryption.decrypt(encrypted.ephemeral, encrypted.mac, encrypted.ciphertext); - console.log(TEST_TEXT, "->", decrypted); - expect(decrypted).toEqual(TEST_TEXT); - }); - - it('should pickle and unpickle', function () { - var TEST_TEXT = 'têst1'; - var pubkey = decryption.generate_key(); - encryption.set_recipient_key(pubkey); - var encrypted = encryption.encrypt(TEST_TEXT); - - var PICKLE_KEY = 'secret_key'; - var pickle = decryption.pickle(PICKLE_KEY); - - var new_decryption = new Olm.PkDecryption(); - var new_pubkey = new_decryption.unpickle(PICKLE_KEY, pickle); - expect(new_pubkey).toEqual(pubkey); - var decrypted = new_decryption.decrypt(encrypted.ephemeral, encrypted.mac, encrypted.ciphertext); - console.log(TEST_TEXT, "->", decrypted); - expect(decrypted).toEqual(TEST_TEXT); - new_decryption.free(); - }); - - it('should sign and verify', function () { - var seed = new Uint8Array([ - 0x77, 0x07, 0x6D, 0x0A, 0x73, 0x18, 0xA5, 0x7D, - 0x3C, 0x16, 0xC1, 0x72, 0x51, 0xB2, 0x66, 0x45, - 0xDF, 0x4C, 0x2F, 0x87, 0xEB, 0xC0, 0x99, 0x2A, - 0xB1, 0x77, 0xFB, 0xA5, 0x1D, 0xB9, 0x2C, 0x2A - ]); - - var TEST_TEXT = "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."; - //var seed = signing.generate_seed(); - var pubkey = signing.init_with_seed(seed); - var sig = signing.sign(TEST_TEXT); - - var util = new Olm.Utility(); - util.ed25519_verify(pubkey, TEST_TEXT, sig); - var verifyFailure; - try { - util.ed25519_verify(pubkey, TEST_TEXT, 'p' + sig.slice(1)); - } catch (e) { - verifyFailure = e; - } - expect(verifyFailure).not.toBeNull(); - util.free(); - }); -}); diff --git a/javascript/test/sas.spec.js b/javascript/test/sas.spec.js deleted file mode 100644 index 4ab4120..0000000 --- a/javascript/test/sas.spec.js +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright 2018 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. -*/ - -var Olm = require('../olm'); - -describe("sas", function() { - var alice, bob; - - beforeEach(async function(done) { - Olm.init().then(function() { - alice = new Olm.SAS(); - bob = new Olm.SAS(); - - done(); - }); - }); - - afterEach(function () { - if (alice !== undefined) { - alice.free(); - alice = undefined; - } - if (bob !== undefined) { - bob.free(); - bob = undefined; - } - }); - - it('should create matching SAS bytes', function () { - alice.set_their_key(bob.get_pubkey()); - bob.set_their_key(alice.get_pubkey()); - expect(alice.generate_bytes("SAS", 5).toString()).toEqual(bob.generate_bytes("SAS", 5).toString()); - }); - - it('should create matching MACs', function () { - alice.set_their_key(bob.get_pubkey()); - bob.set_their_key(alice.get_pubkey()); - expect(alice.calculate_mac("test", "MAC").toString()).toEqual(bob.calculate_mac("test", "MAC").toString()); - }); - - it('should fail to generate bytes if their key is not set', function () { - expect(alice.is_their_key_set()).toBeFalsy(); - expect(() => { - alice.generate_bytes("SAS", 5); - }).toThrow(); - alice.set_their_key(bob.get_pubkey()); - expect(alice.is_their_key_set()).toBeTruthy(); - }); -}); diff --git a/jenkins.sh b/jenkins.sh deleted file mode 100755 index 1dc6b58..0000000 --- a/jenkins.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -set -e - -make clean -rm -f olm-*.tgz - -make lib -make test - -. ~/.emsdk_set_env.sh -make js -(cd javascript && npm install && npm run test) -npm pack javascript diff --git a/lib/crypto-algorithms/.gitignore b/lib/crypto-algorithms/.gitignore new file mode 100644 index 0000000..636c6b9 --- /dev/null +++ b/lib/crypto-algorithms/.gitignore @@ -0,0 +1,5 @@ +# Compiled sibs files +sibs-build/ +compile_commands.json +tests/sibs-build/ +tests/compile_commands.json diff --git a/lib/crypto-algorithms/aes_test.c b/lib/crypto-algorithms/aes_test.c deleted file mode 100644 index d49726d..0000000 --- a/lib/crypto-algorithms/aes_test.c +++ /dev/null @@ -1,276 +0,0 @@ -/*********************************************************************
-* Filename: aes_test.c
-* Author: Brad Conte (brad AT bradconte.com)
-* Copyright:
-* Disclaimer: This code is presented "as is" without any guarantees.
-* Details: Performs known-answer tests on the corresponding AES
- implementation. These tests do not encompass the full
- range of available test vectors and are not sufficient
- for FIPS-140 certification. However, if the tests pass
- it is very, very likely that the code is correct and was
- compiled properly. This code also serves as
- example usage of the functions.
-*********************************************************************/
-
-/*************************** HEADER FILES ***************************/
-#include <stdio.h>
-#include <memory.h>
-#include "aes.h"
-
-/*********************** FUNCTION DEFINITIONS ***********************/
-void print_hex(BYTE str[], int len)
-{
- int idx;
-
- for(idx = 0; idx < len; idx++)
- printf("%02x", str[idx]);
-}
-
-int aes_ecb_test()
-{
- WORD key_schedule[60], idx;
- BYTE enc_buf[128];
- BYTE plaintext[2][16] = {
- {0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a},
- {0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51}
- };
- BYTE ciphertext[2][16] = {
- {0xf3,0xee,0xd1,0xbd,0xb5,0xd2,0xa0,0x3c,0x06,0x4b,0x5a,0x7e,0x3d,0xb1,0x81,0xf8},
- {0x59,0x1c,0xcb,0x10,0xd4,0x10,0xed,0x26,0xdc,0x5b,0xa7,0x4a,0x31,0x36,0x28,0x70}
- };
- BYTE key[1][32] = {
- {0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4}
- };
- int pass = 1;
-
- // Raw ECB mode.
- //printf("* ECB mode:\n");
- aes_key_setup(key[0], key_schedule, 256);
- //printf( "Key : ");
- //print_hex(key[0], 32);
-
- for(idx = 0; idx < 2; idx++) {
- aes_encrypt(plaintext[idx], enc_buf, key_schedule, 256);
- //printf("\nPlaintext : ");
- //print_hex(plaintext[idx], 16);
- //printf("\n-encrypted to: ");
- //print_hex(enc_buf, 16);
- pass = pass && !memcmp(enc_buf, ciphertext[idx], 16);
-
- aes_decrypt(ciphertext[idx], enc_buf, key_schedule, 256);
- //printf("\nCiphertext : ");
- //print_hex(ciphertext[idx], 16);
- //printf("\n-decrypted to: ");
- //print_hex(enc_buf, 16);
- pass = pass && !memcmp(enc_buf, plaintext[idx], 16);
-
- //printf("\n\n");
- }
-
- return(pass);
-}
-
-int aes_cbc_test()
-{
- WORD key_schedule[60];
- BYTE enc_buf[128];
- BYTE plaintext[1][32] = {
- {0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a,0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51}
- };
- BYTE ciphertext[2][32] = {
- {0xf5,0x8c,0x4c,0x04,0xd6,0xe5,0xf1,0xba,0x77,0x9e,0xab,0xfb,0x5f,0x7b,0xfb,0xd6,0x9c,0xfc,0x4e,0x96,0x7e,0xdb,0x80,0x8d,0x67,0x9f,0x77,0x7b,0xc6,0x70,0x2c,0x7d}
- };
- BYTE iv[1][16] = {
- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}
- };
- BYTE key[1][32] = {
- {0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4}
- };
- int pass = 1;
-
- //printf("* CBC mode:\n");
- aes_key_setup(key[0], key_schedule, 256);
-
- //printf( "Key : ");
- //print_hex(key[0], 32);
- //printf("\nIV : ");
- //print_hex(iv[0], 16);
-
- aes_encrypt_cbc(plaintext[0], 32, enc_buf, key_schedule, 256, iv[0]);
- //printf("\nPlaintext : ");
- //print_hex(plaintext[0], 32);
- //printf("\n-encrypted to: ");
- //print_hex(enc_buf, 32);
- //printf("\nCiphertext : ");
- //print_hex(ciphertext[0], 32);
- pass = pass && !memcmp(enc_buf, ciphertext[0], 32);
-
- //printf("\n\n");
- return(pass);
-}
-
-int aes_ctr_test()
-{
- WORD key_schedule[60];
- BYTE enc_buf[128];
- BYTE plaintext[1][32] = {
- {0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a,0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51}
- };
- BYTE ciphertext[1][32] = {
- {0x60,0x1e,0xc3,0x13,0x77,0x57,0x89,0xa5,0xb7,0xa7,0xf5,0x04,0xbb,0xf3,0xd2,0x28,0xf4,0x43,0xe3,0xca,0x4d,0x62,0xb5,0x9a,0xca,0x84,0xe9,0x90,0xca,0xca,0xf5,0xc5}
- };
- BYTE iv[1][16] = {
- {0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff},
- };
- BYTE key[1][32] = {
- {0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4}
- };
- int pass = 1;
-
- //printf("* CTR mode:\n");
- aes_key_setup(key[0], key_schedule, 256);
-
- //printf( "Key : ");
- //print_hex(key[0], 32);
- //printf("\nIV : ");
- //print_hex(iv[0], 16);
-
- aes_encrypt_ctr(plaintext[0], 32, enc_buf, key_schedule, 256, iv[0]);
- //printf("\nPlaintext : ");
- //print_hex(plaintext[0], 32);
- //printf("\n-encrypted to: ");
- //print_hex(enc_buf, 32);
- pass = pass && !memcmp(enc_buf, ciphertext[0], 32);
-
- aes_decrypt_ctr(ciphertext[0], 32, enc_buf, key_schedule, 256, iv[0]);
- //printf("\nCiphertext : ");
- //print_hex(ciphertext[0], 32);
- //printf("\n-decrypted to: ");
- //print_hex(enc_buf, 32);
- pass = pass && !memcmp(enc_buf, plaintext[0], 32);
-
- //printf("\n\n");
- return(pass);
-}
-
-int aes_ccm_test()
-{
- int mac_auth;
- WORD enc_buf_len;
- BYTE enc_buf[128];
- BYTE plaintext[3][32] = {
- {0x20,0x21,0x22,0x23},
- {0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f},
- {0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}
- };
- BYTE assoc[3][32] = {
- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07},
- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f},
- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13}
- };
- BYTE ciphertext[3][32 + 16] = {
- {0x71,0x62,0x01,0x5b,0x4d,0xac,0x25,0x5d},
- {0xd2,0xa1,0xf0,0xe0,0x51,0xea,0x5f,0x62,0x08,0x1a,0x77,0x92,0x07,0x3d,0x59,0x3d,0x1f,0xc6,0x4f,0xbf,0xac,0xcd},
- {0xe3,0xb2,0x01,0xa9,0xf5,0xb7,0x1a,0x7a,0x9b,0x1c,0xea,0xec,0xcd,0x97,0xe7,0x0b,0x61,0x76,0xaa,0xd9,0xa4,0x42,0x8a,0xa5,0x48,0x43,0x92,0xfb,0xc1,0xb0,0x99,0x51}
- };
- BYTE iv[3][16] = {
- {0x10,0x11,0x12,0x13,0x14,0x15,0x16},
- {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17},
- {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b}
- };
- BYTE key[1][32] = {
- {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f}
- };
- int pass = 1;
-
- //printf("* CCM mode:\n");
- //printf("Key : ");
- //print_hex(key[0], 16);
-
- //print_hex(plaintext[0], 4);
- //print_hex(assoc[0], 8);
- //print_hex(ciphertext[0], 8);
- //print_hex(iv[0], 7);
- //print_hex(key[0], 16);
-
- aes_encrypt_ccm(plaintext[0], 4, assoc[0], 8, iv[0], 7, enc_buf, &enc_buf_len, 4, key[0], 128);
- //printf("\nNONCE : ");
- //print_hex(iv[0], 7);
- //printf("\nAssoc. Data : ");
- //print_hex(assoc[0], 8);
- //printf("\nPayload : ");
- //print_hex(plaintext[0], 4);
- //printf("\n-encrypted to: ");
- //print_hex(enc_buf, enc_buf_len);
- pass = pass && !memcmp(enc_buf, ciphertext[0], enc_buf_len);
-
- aes_decrypt_ccm(ciphertext[0], 8, assoc[0], 8, iv[0], 7, enc_buf, &enc_buf_len, 4, &mac_auth, key[0], 128);
- //printf("\n-Ciphertext : ");
- //print_hex(ciphertext[0], 8);
- //printf("\n-decrypted to: ");
- //print_hex(enc_buf, enc_buf_len);
- //printf("\nAuthenticated: %d ", mac_auth);
- pass = pass && !memcmp(enc_buf, plaintext[0], enc_buf_len) && mac_auth;
-
-
- aes_encrypt_ccm(plaintext[1], 16, assoc[1], 16, iv[1], 8, enc_buf, &enc_buf_len, 6, key[0], 128);
- //printf("\n\nNONCE : ");
- //print_hex(iv[1], 8);
- //printf("\nAssoc. Data : ");
- //print_hex(assoc[1], 16);
- //printf("\nPayload : ");
- //print_hex(plaintext[1], 16);
- //printf("\n-encrypted to: ");
- //print_hex(enc_buf, enc_buf_len);
- pass = pass && !memcmp(enc_buf, ciphertext[1], enc_buf_len);
-
- aes_decrypt_ccm(ciphertext[1], 22, assoc[1], 16, iv[1], 8, enc_buf, &enc_buf_len, 6, &mac_auth, key[0], 128);
- //printf("\n-Ciphertext : ");
- //print_hex(ciphertext[1], 22);
- //printf("\n-decrypted to: ");
- //print_hex(enc_buf, enc_buf_len);
- //printf("\nAuthenticated: %d ", mac_auth);
- pass = pass && !memcmp(enc_buf, plaintext[1], enc_buf_len) && mac_auth;
-
-
- aes_encrypt_ccm(plaintext[2], 24, assoc[2], 20, iv[2], 12, enc_buf, &enc_buf_len, 8, key[0], 128);
- //printf("\n\nNONCE : ");
- //print_hex(iv[2], 12);
- //printf("\nAssoc. Data : ");
- //print_hex(assoc[2], 20);
- //printf("\nPayload : ");
- //print_hex(plaintext[2], 24);
- //printf("\n-encrypted to: ");
- //print_hex(enc_buf, enc_buf_len);
- pass = pass && !memcmp(enc_buf, ciphertext[2], enc_buf_len);
-
- aes_decrypt_ccm(ciphertext[2], 32, assoc[2], 20, iv[2], 12, enc_buf, &enc_buf_len, 8, &mac_auth, key[0], 128);
- //printf("\n-Ciphertext : ");
- //print_hex(ciphertext[2], 32);
- //printf("\n-decrypted to: ");
- //print_hex(enc_buf, enc_buf_len);
- //printf("\nAuthenticated: %d ", mac_auth);
- pass = pass && !memcmp(enc_buf, plaintext[2], enc_buf_len) && mac_auth;
-
- //printf("\n\n");
- return(pass);
-}
-
-int aes_test()
-{
- int pass = 1;
-
- pass = pass && aes_ecb_test();
- pass = pass && aes_cbc_test();
- pass = pass && aes_ctr_test();
- pass = pass && aes_ccm_test();
-
- return(pass);
-}
-
-int main(int argc, char *argv[])
-{
- printf("AES Tests: %s\n", aes_test() ? "SUCCEEDED" : "FAILED");
-
- return(0);
-}
diff --git a/lib/crypto-algorithms/arcfour_test.c b/lib/crypto-algorithms/arcfour_test.c deleted file mode 100644 index 985f8a7..0000000 --- a/lib/crypto-algorithms/arcfour_test.c +++ /dev/null @@ -1,47 +0,0 @@ -/********************************************************************* -* Filename: arcfour_test.c -* Author: Brad Conte (brad AT bradconte.com) -* Copyright: -* Disclaimer: This code is presented "as is" without any guarantees. -* Details: Performs known-answer tests on the corresponding ARCFOUR - implementation. These tests do not encompass the full - range of available test vectors, however, if the tests - pass it is very, very likely that the code is correct - and was compiled properly. This code also serves as - example usage of the functions. -*********************************************************************/ - -/*************************** HEADER FILES ***************************/ -#include <stdio.h> -#include <memory.h> -#include "arcfour.h" - -/*********************** FUNCTION DEFINITIONS ***********************/ -int rc4_test() -{ - BYTE state[256]; - BYTE key[3][10] = {{"Key"}, {"Wiki"}, {"Secret"}}; - BYTE stream[3][10] = {{0xEB,0x9F,0x77,0x81,0xB7,0x34,0xCA,0x72,0xA7,0x19}, - {0x60,0x44,0xdb,0x6d,0x41,0xb7}, - {0x04,0xd4,0x6b,0x05,0x3c,0xa8,0x7b,0x59}}; - int stream_len[3] = {10,6,8}; - BYTE buf[1024]; - int idx; - int pass = 1; - - // Only test the output stream. Note that the state can be reused. - for (idx = 0; idx < 3; idx++) { - arcfour_key_setup(state, key[idx], strlen(key[idx])); - arcfour_generate_stream(state, buf, stream_len[idx]); - pass = pass && !memcmp(stream[idx], buf, stream_len[idx]); - } - - return(pass); -} - -int main() -{ - printf("ARCFOUR tests: %s\n", rc4_test() ? "SUCCEEDED" : "FAILED"); - - return(0); -} diff --git a/lib/crypto-algorithms/base64_test.c b/lib/crypto-algorithms/base64_test.c deleted file mode 100644 index c59cc98..0000000 --- a/lib/crypto-algorithms/base64_test.c +++ /dev/null @@ -1,54 +0,0 @@ -/********************************************************************* -* Filename: blowfish_test.c -* Author: Brad Conte (brad AT bradconte.com) -* Copyright: -* Disclaimer: This code is presented "as is" without any guarantees. -* Details: Performs known-answer tests on the corresponding Base64 - implementation. These tests do not encompass the full - range of available test vectors, however, if the tests - pass it is very, very likely that the code is correct - and was compiled properly. This code also serves as - example usage of the functions. -*********************************************************************/ - -/*************************** HEADER FILES ***************************/ -#include <stdio.h> -#include <memory.h> -#include "base64.h" - -/*********************** FUNCTION DEFINITIONS ***********************/ -int base64_test() -{ - BYTE text[3][1024] = {{"fo"}, - {"foobar"}, - {"Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure."}}; - BYTE code[3][1024] = {{"Zm8="}, - {"Zm9vYmFy"}, - {"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz\nIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg\ndGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu\ndWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo\nZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4="}}; - BYTE buf[1024]; - size_t buf_len; - int pass = 1; - int idx; - - for (idx = 0; idx < 3; idx++) { - buf_len = base64_encode(text[idx], buf, strlen(text[idx]), 1); - pass = pass && ((buf_len == strlen(code[idx])) && - (buf_len == base64_encode(text[idx], NULL, strlen(text[idx]), 1))); - pass = pass && !strcmp(code[idx], buf); - - memset(buf, 0, sizeof(buf)); - buf_len = base64_decode(code[idx], buf, strlen(code[idx])); - pass = pass && ((buf_len == strlen(text[idx])) && - (buf_len == base64_decode(code[idx], NULL, strlen(code[idx])))); - pass = pass && !strcmp(text[idx], buf); - } - - return(pass); -} - -int main() -{ - printf("Base64 tests: %s\n", base64_test() ? "PASSED" : "FAILED"); - - return 0; -} diff --git a/lib/crypto-algorithms/blowfish_test.c b/lib/crypto-algorithms/blowfish_test.c deleted file mode 100644 index 0f0aa38..0000000 --- a/lib/crypto-algorithms/blowfish_test.c +++ /dev/null @@ -1,68 +0,0 @@ -/********************************************************************* -* Filename: blowfish_test.c -* Author: Brad Conte (brad AT bradconte.com) -* Copyright: -* Disclaimer: This code is presented "as is" without any guarantees. -* Details: Performs known-answer tests on the corresponding Blowfish - implementation. These tests do not encompass the full - range of available test vectors, however, if the tests - pass it is very, very likely that the code is correct - and was compiled properly. This code also serves as - example usage of the functions. -*********************************************************************/ - -/*************************** HEADER FILES ***************************/ -#include <stdio.h> -#include <memory.h> -#include "blowfish.h" - -/*********************** FUNCTION DEFINITIONS ***********************/ -int blowfish_test() -{ - BYTE key1[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - BYTE key2[8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; - BYTE key3[24] = {0xF0,0xE1,0xD2,0xC3,0xB4,0xA5,0x96,0x87, - 0x78,0x69,0x5A,0x4B,0x3C,0x2D,0x1E,0x0F, - 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77}; - BYTE p1[BLOWFISH_BLOCK_SIZE] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - BYTE p2[BLOWFISH_BLOCK_SIZE] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; - BYTE p3[BLOWFISH_BLOCK_SIZE] = {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}; - - BYTE c1[BLOWFISH_BLOCK_SIZE] = {0x4e,0xf9,0x97,0x45,0x61,0x98,0xdd,0x78}; - BYTE c2[BLOWFISH_BLOCK_SIZE] = {0x51,0x86,0x6f,0xd5,0xb8,0x5e,0xcb,0x8a}; - BYTE c3[BLOWFISH_BLOCK_SIZE] = {0x05,0x04,0x4b,0x62,0xfa,0x52,0xd0,0x80}; - - BYTE enc_buf[BLOWFISH_BLOCK_SIZE]; - BLOWFISH_KEY key; - int pass = 1; - - // Test vector 1. - blowfish_key_setup(key1, &key, BLOWFISH_BLOCK_SIZE); - blowfish_encrypt(p1, enc_buf, &key); - pass = pass && !memcmp(c1, enc_buf, BLOWFISH_BLOCK_SIZE); - blowfish_decrypt(c1, enc_buf, &key); - pass = pass && !memcmp(p1, enc_buf, BLOWFISH_BLOCK_SIZE); - - // Test vector 2. - blowfish_key_setup(key2, &key, BLOWFISH_BLOCK_SIZE); - blowfish_encrypt(p2, enc_buf, &key); - pass = pass && !memcmp(c2, enc_buf, BLOWFISH_BLOCK_SIZE); - blowfish_decrypt(c2, enc_buf, &key); - pass = pass && !memcmp(p2, enc_buf, BLOWFISH_BLOCK_SIZE); - - // Test vector 3. - blowfish_key_setup(key3, &key, 24); - blowfish_encrypt(p3, enc_buf, &key); - pass = pass && !memcmp(c3, enc_buf, BLOWFISH_BLOCK_SIZE); - blowfish_decrypt(c3, enc_buf, &key); - pass = pass && !memcmp(p3, enc_buf, BLOWFISH_BLOCK_SIZE); - - return(pass); -} - -int main() -{ - printf("Blowfish tests: %s\n", blowfish_test() ? "SUCCEEDED" : "FAILED"); - - return(0); -} diff --git a/lib/crypto-algorithms/des_test.c b/lib/crypto-algorithms/des_test.c deleted file mode 100644 index 3e46134..0000000 --- a/lib/crypto-algorithms/des_test.c +++ /dev/null @@ -1,83 +0,0 @@ -/********************************************************************* -* Filename: des_test.c -* Author: Brad Conte (brad AT bradconte.com) -* Copyright: -* Disclaimer: This code is presented "as is" without any guarantees. -* Details: Performs known-answer tests on the corresponding DES - implementation. These tests do not encompass the full - range of available test vectors, however, if the tests - pass it is very, very likely that the code is correct - and was compiled properly. This code also serves as - example usage of the functions. -*********************************************************************/ - -/*************************** HEADER FILES ***************************/ -#include <stdio.h> -#include <memory.h> -#include "des.h" - -/*********************** FUNCTION DEFINITIONS ***********************/ -int des_test() -{ - BYTE pt1[DES_BLOCK_SIZE] = {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xE7}; - BYTE pt2[DES_BLOCK_SIZE] = {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}; - BYTE pt3[DES_BLOCK_SIZE] = {0x54,0x68,0x65,0x20,0x71,0x75,0x66,0x63}; - BYTE ct1[DES_BLOCK_SIZE] = {0xc9,0x57,0x44,0x25,0x6a,0x5e,0xd3,0x1d}; - BYTE ct2[DES_BLOCK_SIZE] = {0x85,0xe8,0x13,0x54,0x0f,0x0a,0xb4,0x05}; - BYTE ct3[DES_BLOCK_SIZE] = {0xc9,0x57,0x44,0x25,0x6a,0x5e,0xd3,0x1d}; - BYTE ct4[DES_BLOCK_SIZE] = {0xA8,0x26,0xFD,0x8C,0xE5,0x3B,0x85,0x5F}; - BYTE key1[DES_BLOCK_SIZE] = {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}; - BYTE key2[DES_BLOCK_SIZE] = {0x13,0x34,0x57,0x79,0x9B,0xBC,0xDF,0xF1}; - BYTE three_key1[DES_BLOCK_SIZE * 3] = {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, - 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, - 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}; - BYTE three_key2[DES_BLOCK_SIZE * 3] = {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, - 0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,0x01, - 0x45,0x67,0x89,0xAB,0xCD,0xEF,0x01,0x23}; - - BYTE schedule[16][6]; - BYTE three_schedule[3][16][6]; - BYTE buf[DES_BLOCK_SIZE]; - int pass = 1; - - des_key_setup(key1, schedule, DES_ENCRYPT); - des_crypt(pt1, buf, schedule); - pass = pass && !memcmp(ct1, buf, DES_BLOCK_SIZE); - - des_key_setup(key1, schedule, DES_DECRYPT); - des_crypt(ct1, buf, schedule); - pass = pass && !memcmp(pt1, buf, DES_BLOCK_SIZE); - - des_key_setup(key2, schedule, DES_ENCRYPT); - des_crypt(pt2, buf, schedule); - pass = pass && !memcmp(ct2, buf, DES_BLOCK_SIZE); - - des_key_setup(key2, schedule, DES_DECRYPT); - des_crypt(ct2, buf, schedule); - pass = pass && !memcmp(pt2, buf, DES_BLOCK_SIZE); - - three_des_key_setup(three_key1, three_schedule, DES_ENCRYPT); - three_des_crypt(pt1, buf, three_schedule); - pass = pass && !memcmp(ct3, buf, DES_BLOCK_SIZE); - - three_des_key_setup(three_key1, three_schedule, DES_DECRYPT); - three_des_crypt(ct3, buf, three_schedule); - pass = pass && !memcmp(pt1, buf, DES_BLOCK_SIZE); - - three_des_key_setup(three_key2, three_schedule, DES_ENCRYPT); - three_des_crypt(pt3, buf, three_schedule); - pass = pass && !memcmp(ct4, buf, DES_BLOCK_SIZE); - - three_des_key_setup(three_key2, three_schedule, DES_DECRYPT); - three_des_crypt(ct4, buf, three_schedule); - pass = pass && !memcmp(pt3, buf, DES_BLOCK_SIZE); - - return(pass); -} - -int main() -{ - printf("DES test: %s\n", des_test() ? "SUCCEEDED" : "FAILED"); - - return(0); -} diff --git a/lib/crypto-algorithms/md2_test.c b/lib/crypto-algorithms/md2_test.c deleted file mode 100644 index 883f20a..0000000 --- a/lib/crypto-algorithms/md2_test.c +++ /dev/null @@ -1,58 +0,0 @@ -/********************************************************************* -* Filename: md2_test.c -* Author: Brad Conte (brad AT bradconte.com) -* Copyright: -* Disclaimer: This code is presented "as is" without any guarantees. -* Details: Performs known-answer tests on the corresponding MD2 - implementation. These tests do not encompass the full - range of available test vectors, however, if the tests - pass it is very, very likely that the code is correct - and was compiled properly. This code also serves as - example usage of the functions. -*********************************************************************/ - -/*************************** HEADER FILES ***************************/ -#include <stdio.h> -#include <string.h> -#include <memory.h> -#include "md2.h" - -/*********************** FUNCTION DEFINITIONS ***********************/ -int md2_test() -{ - BYTE text1[] = {"abc"}; - BYTE text2[] = {"abcdefghijklmnopqrstuvwxyz"}; - BYTE text3_1[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"}; - BYTE text3_2[] = {"fghijklmnopqrstuvwxyz0123456789"}; - BYTE hash1[MD2_BLOCK_SIZE] = {0xda,0x85,0x3b,0x0d,0x3f,0x88,0xd9,0x9b,0x30,0x28,0x3a,0x69,0xe6,0xde,0xd6,0xbb}; - BYTE hash2[MD2_BLOCK_SIZE] = {0x4e,0x8d,0xdf,0xf3,0x65,0x02,0x92,0xab,0x5a,0x41,0x08,0xc3,0xaa,0x47,0x94,0x0b}; - BYTE hash3[MD2_BLOCK_SIZE] = {0xda,0x33,0xde,0xf2,0xa4,0x2d,0xf1,0x39,0x75,0x35,0x28,0x46,0xc3,0x03,0x38,0xcd}; - BYTE buf[16]; - MD2_CTX ctx; - int pass = 1; - - md2_init(&ctx); - md2_update(&ctx, text1, strlen(text1)); - md2_final(&ctx, buf); - pass = pass && !memcmp(hash1, buf, MD2_BLOCK_SIZE); - - // Note that the MD2 object can be re-used. - md2_init(&ctx); - md2_update(&ctx, text2, strlen(text2)); - md2_final(&ctx, buf); - pass = pass && !memcmp(hash2, buf, MD2_BLOCK_SIZE); - - // Note that the data is added in two chunks. - md2_init(&ctx); - md2_update(&ctx, text3_1, strlen(text3_1)); - md2_update(&ctx, text3_2, strlen(text3_2)); - md2_final(&ctx, buf); - pass = pass && !memcmp(hash3, buf, MD2_BLOCK_SIZE); - - return(pass); -} - -int main() -{ - printf("MD2 tests: %s\n", md2_test() ? "SUCCEEDED" : "FAILED"); -} diff --git a/lib/crypto-algorithms/md5_test.c b/lib/crypto-algorithms/md5_test.c deleted file mode 100644 index e945c8b..0000000 --- a/lib/crypto-algorithms/md5_test.c +++ /dev/null @@ -1,60 +0,0 @@ -/********************************************************************* -* Filename: md5_test.c -* Author: Brad Conte (brad AT bradconte.com) -* Copyright: -* Disclaimer: This code is presented "as is" without any guarantees. -* Details: Performs known-answer tests on the corresponding MD5 - implementation. These tests do not encompass the full - range of available test vectors, however, if the tests - pass it is very, very likely that the code is correct - and was compiled properly. This code also serves as - example usage of the functions. -*********************************************************************/ - -/*************************** HEADER FILES ***************************/ -#include <stdio.h> -#include <memory.h> -#include <string.h> -#include "md5.h" - -/*********************** FUNCTION DEFINITIONS ***********************/ -int md5_test() -{ - BYTE text1[] = {""}; - BYTE text2[] = {"abc"}; - BYTE text3_1[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"}; - BYTE text3_2[] = {"fghijklmnopqrstuvwxyz0123456789"}; - BYTE hash1[MD5_BLOCK_SIZE] = {0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,0x7e}; - BYTE hash2[MD5_BLOCK_SIZE] = {0x90,0x01,0x50,0x98,0x3c,0xd2,0x4f,0xb0,0xd6,0x96,0x3f,0x7d,0x28,0xe1,0x7f,0x72}; - BYTE hash3[MD5_BLOCK_SIZE] = {0xd1,0x74,0xab,0x98,0xd2,0x77,0xd9,0xf5,0xa5,0x61,0x1c,0x2c,0x9f,0x41,0x9d,0x9f}; - BYTE buf[16]; - MD5_CTX ctx; - int pass = 1; - - md5_init(&ctx); - md5_update(&ctx, text1, strlen(text1)); - md5_final(&ctx, buf); - pass = pass && !memcmp(hash1, buf, MD5_BLOCK_SIZE); - - // Note the MD5 object can be reused. - md5_init(&ctx); - md5_update(&ctx, text2, strlen(text2)); - md5_final(&ctx, buf); - pass = pass && !memcmp(hash2, buf, MD5_BLOCK_SIZE); - - // Note the data is being added in two chunks. - md5_init(&ctx); - md5_update(&ctx, text3_1, strlen(text3_1)); - md5_update(&ctx, text3_2, strlen(text3_2)); - md5_final(&ctx, buf); - pass = pass && !memcmp(hash3, buf, MD5_BLOCK_SIZE); - - return(pass); -} - -int main() -{ - printf("MD5 tests: %s\n", md5_test() ? "SUCCEEDED" : "FAILED"); - - return(0); -} diff --git a/lib/crypto-algorithms/project.conf b/lib/crypto-algorithms/project.conf new file mode 100644 index 0000000..776dc58 --- /dev/null +++ b/lib/crypto-algorithms/project.conf @@ -0,0 +1,5 @@ +[package] +name = "crypto-algorithms" +type = "static" +version = "0.1.0" +platforms = ["any"] diff --git a/lib/crypto-algorithms/rot-13_test.c b/lib/crypto-algorithms/rot-13_test.c deleted file mode 100644 index a6fd01d..0000000 --- a/lib/crypto-algorithms/rot-13_test.c +++ /dev/null @@ -1,44 +0,0 @@ -/********************************************************************* -* Filename: rot-13_test.c -* Author: Brad Conte (brad AT bradconte.com) -* Copyright: -* Disclaimer: This code is presented "as is" without any guarantees. -* Details: Performs known-answer tests on the corresponding ROT-13 - implementation. These tests do not encompass the full - range of available test vectors, however, if the tests - pass it is very, very likely that the code is correct - and was compiled properly. This code also serves as - example usage of the functions. -*********************************************************************/ - -/*************************** HEADER FILES ***************************/ -#include <stdio.h> -#include <string.h> -#include "rot-13.h" - -/*********************** FUNCTION DEFINITIONS ***********************/ -int rot13_test() -{ - char text[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"}; - char code[] = {"NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm"}; - char buf[1024]; - int pass = 1; - - // To encode, just apply ROT-13. - strcpy(buf, text); - rot13(buf); - pass = pass && !strcmp(code, buf); - - // To decode, just re-apply ROT-13. - rot13(buf); - pass = pass && !strcmp(text, buf); - - return(pass); -} - -int main() -{ - printf("ROT-13 tests: %s\n", rot13_test() ? "SUCCEEDED" : "FAILED"); - - return(0); -} diff --git a/lib/crypto-algorithms/sha1_test.c b/lib/crypto-algorithms/sha1_test.c deleted file mode 100644 index 6c78f7d..0000000 --- a/lib/crypto-algorithms/sha1_test.c +++ /dev/null @@ -1,58 +0,0 @@ -/********************************************************************* -* Filename: sha1_test.c -* Author: Brad Conte (brad AT bradconte.com) -* Copyright: -* Disclaimer: This code is presented "as is" without any guarantees. -* Details: Performs known-answer tests on the corresponding SHA1 - implementation. These tests do not encompass the full - range of available test vectors, however, if the tests - pass it is very, very likely that the code is correct - and was compiled properly. This code also serves as - example usage of the functions. -*********************************************************************/ - -/*************************** HEADER FILES ***************************/ -#include <stdio.h> -#include <memory.h> -#include <string.h> -#include "sha1.h" - -/*********************** FUNCTION DEFINITIONS ***********************/ -int sha1_test() -{ - BYTE text1[] = {"abc"}; - BYTE text2[] = {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}; - BYTE text3[] = {"aaaaaaaaaa"}; - BYTE hash1[SHA1_BLOCK_SIZE] = {0xa9,0x99,0x3e,0x36,0x47,0x06,0x81,0x6a,0xba,0x3e,0x25,0x71,0x78,0x50,0xc2,0x6c,0x9c,0xd0,0xd8,0x9d}; - BYTE hash2[SHA1_BLOCK_SIZE] = {0x84,0x98,0x3e,0x44,0x1c,0x3b,0xd2,0x6e,0xba,0xae,0x4a,0xa1,0xf9,0x51,0x29,0xe5,0xe5,0x46,0x70,0xf1}; - BYTE hash3[SHA1_BLOCK_SIZE] = {0x34,0xaa,0x97,0x3c,0xd4,0xc4,0xda,0xa4,0xf6,0x1e,0xeb,0x2b,0xdb,0xad,0x27,0x31,0x65,0x34,0x01,0x6f}; - BYTE buf[SHA1_BLOCK_SIZE]; - int idx; - SHA1_CTX ctx; - int pass = 1; - - sha1_init(&ctx); - sha1_update(&ctx, text1, strlen(text1)); - sha1_final(&ctx, buf); - pass = pass && !memcmp(hash1, buf, SHA1_BLOCK_SIZE); - - sha1_init(&ctx); - sha1_update(&ctx, text2, strlen(text2)); - sha1_final(&ctx, buf); - pass = pass && !memcmp(hash2, buf, SHA1_BLOCK_SIZE); - - sha1_init(&ctx); - for (idx = 0; idx < 100000; ++idx) - sha1_update(&ctx, text3, strlen(text3)); - sha1_final(&ctx, buf); - pass = pass && !memcmp(hash3, buf, SHA1_BLOCK_SIZE); - - return(pass); -} - -int main() -{ - printf("SHA1 tests: %s\n", sha1_test() ? "SUCCEEDED" : "FAILED"); - - return(0); -} diff --git a/lib/crypto-algorithms/sha256_test.c b/lib/crypto-algorithms/sha256_test.c deleted file mode 100644 index 6951c51..0000000 --- a/lib/crypto-algorithms/sha256_test.c +++ /dev/null @@ -1,61 +0,0 @@ -/********************************************************************* -* Filename: sha256.c -* Author: Brad Conte (brad AT bradconte.com) -* Copyright: -* Disclaimer: This code is presented "as is" without any guarantees. -* Details: Performs known-answer tests on the corresponding SHA1 - implementation. These tests do not encompass the full - range of available test vectors, however, if the tests - pass it is very, very likely that the code is correct - and was compiled properly. This code also serves as - example usage of the functions. -*********************************************************************/ - -/*************************** HEADER FILES ***************************/ -#include <stdio.h> -#include <memory.h> -#include <string.h> -#include "sha256.h" - -/*********************** FUNCTION DEFINITIONS ***********************/ -int sha256_test() -{ - BYTE text1[] = {"abc"}; - BYTE text2[] = {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}; - BYTE text3[] = {"aaaaaaaaaa"}; - BYTE hash1[SHA256_BLOCK_SIZE] = {0xba,0x78,0x16,0xbf,0x8f,0x01,0xcf,0xea,0x41,0x41,0x40,0xde,0x5d,0xae,0x22,0x23, - 0xb0,0x03,0x61,0xa3,0x96,0x17,0x7a,0x9c,0xb4,0x10,0xff,0x61,0xf2,0x00,0x15,0xad}; - BYTE hash2[SHA256_BLOCK_SIZE] = {0x24,0x8d,0x6a,0x61,0xd2,0x06,0x38,0xb8,0xe5,0xc0,0x26,0x93,0x0c,0x3e,0x60,0x39, - 0xa3,0x3c,0xe4,0x59,0x64,0xff,0x21,0x67,0xf6,0xec,0xed,0xd4,0x19,0xdb,0x06,0xc1}; - BYTE hash3[SHA256_BLOCK_SIZE] = {0xcd,0xc7,0x6e,0x5c,0x99,0x14,0xfb,0x92,0x81,0xa1,0xc7,0xe2,0x84,0xd7,0x3e,0x67, - 0xf1,0x80,0x9a,0x48,0xa4,0x97,0x20,0x0e,0x04,0x6d,0x39,0xcc,0xc7,0x11,0x2c,0xd0}; - BYTE buf[SHA256_BLOCK_SIZE]; - SHA256_CTX ctx; - int idx; - int pass = 1; - - sha256_init(&ctx); - sha256_update(&ctx, text1, strlen(text1)); - sha256_final(&ctx, buf); - pass = pass && !memcmp(hash1, buf, SHA256_BLOCK_SIZE); - - sha256_init(&ctx); - sha256_update(&ctx, text2, strlen(text2)); - sha256_final(&ctx, buf); - pass = pass && !memcmp(hash2, buf, SHA256_BLOCK_SIZE); - - sha256_init(&ctx); - for (idx = 0; idx < 100000; ++idx) - sha256_update(&ctx, text3, strlen(text3)); - sha256_final(&ctx, buf); - pass = pass && !memcmp(hash3, buf, SHA256_BLOCK_SIZE); - - return(pass); -} - -int main() -{ - printf("SHA-256 tests: %s\n", sha256_test() ? "SUCCEEDED" : "FAILEd"); - - return(0); -} diff --git a/lib/curve25519-donna/.gitignore b/lib/curve25519-donna/.gitignore index ccabede..1d764d7 100644 --- a/lib/curve25519-donna/.gitignore +++ b/lib/curve25519-donna/.gitignore @@ -10,3 +10,10 @@ *.pyc /dist /MANIFEST + + +# Compiled sibs files +sibs-build/ +compile_commands.json +tests/sibs-build/ +tests/compile_commands.json diff --git a/lib/curve25519-donna/contrib/Curve25519Donna.c b/lib/curve25519-donna/contrib/Curve25519Donna.c deleted file mode 100644 index 71b816c..0000000 --- a/lib/curve25519-donna/contrib/Curve25519Donna.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - James Robson - Public domain. -*/ - -#include "Curve25519Donna.h" -#include <stdio.h> -#include <stdlib.h> - -extern void curve25519_donna(unsigned char *output, const unsigned char *a, - const unsigned char *b); - -unsigned char* -as_unsigned_char_array(JNIEnv* env, jbyteArray array, int* len); - -jbyteArray as_byte_array(JNIEnv* env, unsigned char* buf, int len); - - -jbyteArray as_byte_array(JNIEnv* env, unsigned char* buf, int len) { - jbyteArray array = (*env)->NewByteArray(env, len); - (*env)->SetByteArrayRegion(env, array, 0, len, (jbyte*)buf); - - //int i; - //for (i = 0;i < len;++i) printf("%02x",(unsigned int) buf[i]); printf(" "); - //printf("\n"); - - return array; -} - -unsigned char* -as_unsigned_char_array(JNIEnv* env, jbyteArray array, int* len) { - - *len = (*env)->GetArrayLength(env, array); - unsigned char* buf = (unsigned char*)calloc(*len+1, sizeof(char)); - (*env)->GetByteArrayRegion (env, array, 0, *len, (jbyte*)buf); - return buf; - -} - -JNIEXPORT jbyteArray JNICALL Java_Curve25519Donna_curve25519Donna - (JNIEnv *env, jobject obj, jbyteArray a, jbyteArray b) { - - unsigned char o[32] = {0}; - int l1, l2; - unsigned char* a1 = as_unsigned_char_array(env, a, &l1); - unsigned char* b1 = as_unsigned_char_array(env, b, &l2); - - if ( !(l1 == 32 && l2 == 32) ) { - fprintf(stderr, "Error, must be length 32"); - return NULL; - } - - - curve25519_donna(o, (const unsigned char*)a1, (const unsigned char*)b1); - - free(a1); - free(b1); - - return as_byte_array(env, (unsigned char*)o, 32); -} - -JNIEXPORT jbyteArray JNICALL Java_Curve25519Donna_makePrivate - (JNIEnv *env, jobject obj, jbyteArray secret) { - - int len; - unsigned char* k = as_unsigned_char_array(env, secret, &len); - - if (len != 32) { - fprintf(stderr, "Error, must be length 32"); - return NULL; - } - - k[0] &= 248; - k[31] &= 127; - k[31] |= 64; - return as_byte_array(env, k, 32); -} - -JNIEXPORT jbyteArray JNICALL Java_Curve25519Donna_getPublic - (JNIEnv *env, jobject obj, jbyteArray privkey) { - - int len; - unsigned char* private = as_unsigned_char_array(env, privkey, &len); - - if (len != 32) { - fprintf(stderr, "Error, must be length 32"); - return NULL; - } - - unsigned char pubkey[32]; - unsigned char basepoint[32] = {9}; - - curve25519_donna(pubkey, private, basepoint); - return as_byte_array(env, (unsigned char*)pubkey, 32); -} - -JNIEXPORT jbyteArray JNICALL Java_Curve25519Donna_makeSharedSecret - (JNIEnv *env, jobject obj, jbyteArray privkey, jbyteArray their_pubkey) { - - unsigned char shared_secret[32]; - - int l1, l2; - unsigned char* private = as_unsigned_char_array(env, privkey, &l1); - unsigned char* pubkey = as_unsigned_char_array(env, their_pubkey, &l2); - - if ( !(l1 == 32 && l2 == 32) ) { - fprintf(stderr, "Error, must be length 32"); - return NULL; - } - - curve25519_donna(shared_secret, private, pubkey); - return as_byte_array(env, (unsigned char*)shared_secret, 32); -} - -JNIEXPORT void JNICALL Java_Curve25519Donna_helowrld - (JNIEnv *env, jobject obj) { - printf("helowrld\n"); -} diff --git a/lib/curve25519-donna/contrib/Curve25519Donna.h b/lib/curve25519-donna/contrib/Curve25519Donna.h deleted file mode 100644 index 3cd4ca0..0000000 --- a/lib/curve25519-donna/contrib/Curve25519Donna.h +++ /dev/null @@ -1,53 +0,0 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include <jni.h> -/* Header for class Curve25519Donna */ - -#ifndef _Included_Curve25519Donna -#define _Included_Curve25519Donna -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: Curve25519Donna - * Method: curve25519Donna - * Signature: ([B[B)[B - */ -JNIEXPORT jbyteArray JNICALL Java_Curve25519Donna_curve25519Donna - (JNIEnv *, jobject, jbyteArray, jbyteArray); - -/* - * Class: Curve25519Donna - * Method: makePrivate - * Signature: ([B)[B - */ -JNIEXPORT jbyteArray JNICALL Java_Curve25519Donna_makePrivate - (JNIEnv *, jobject, jbyteArray); - -/* - * Class: Curve25519Donna - * Method: getPublic - * Signature: ([B)[B - */ -JNIEXPORT jbyteArray JNICALL Java_Curve25519Donna_getPublic - (JNIEnv *, jobject, jbyteArray); - -/* - * Class: Curve25519Donna - * Method: makeSharedSecret - * Signature: ([B[B)[B - */ -JNIEXPORT jbyteArray JNICALL Java_Curve25519Donna_makeSharedSecret - (JNIEnv *, jobject, jbyteArray, jbyteArray); - -/* - * Class: Curve25519Donna - * Method: helowrld - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_Curve25519Donna_helowrld - (JNIEnv *, jobject); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/lib/curve25519-donna/contrib/Curve25519Donna.java b/lib/curve25519-donna/contrib/Curve25519Donna.java deleted file mode 100644 index e28cb53..0000000 --- a/lib/curve25519-donna/contrib/Curve25519Donna.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - James Robson - Public domain. -*/ - -public class Curve25519Donna { - - final protected static char[] hexArray = "0123456789ABCDEF".toCharArray(); - - public static String bytesToHex(byte[] bytes) { - char[] hexChars = new char[bytes.length * 2]; - int v; - for ( int j = 0; j < bytes.length; j++ ) { - v = bytes[j] & 0xFF; - hexChars[j * 2] = hexArray[v >>> 4]; - hexChars[j * 2 + 1] = hexArray[v & 0x0F]; - } - return new String(hexChars); - } - - public native byte[] curve25519Donna(byte[] a, byte[] b); - public native byte[] makePrivate(byte[] secret); - public native byte[] getPublic(byte[] privkey); - public native byte[] makeSharedSecret(byte[] privkey, byte[] theirPubKey); - public native void helowrld(); - - // Uncomment if your Java is 32-bit: - //static { System.loadLibrary("Curve25519Donna"); } - - // Otherwise, load this 64-bit .jnilib: - static { System.loadLibrary("Curve25519Donna_64"); } - - /* - To give the old tires a kick (OSX): - java -cp `pwd` Curve25519Donna - */ - public static void main (String[] args) { - - Curve25519Donna c = new Curve25519Donna(); - - // These should be 32 bytes long - byte[] user1Secret = "abcdefghijklmnopqrstuvwxyz123456".getBytes(); - byte[] user2Secret = "654321zyxwvutsrqponmlkjihgfedcba".getBytes(); - - - // You can use the curve function directly... - - //byte[] o = c.curve25519Donna(a, b); - //System.out.println("o = " + bytesToHex(o)); - - - // ... but it's not really necessary. Just use the following - // convenience methods: - - byte[] privKey = c.makePrivate(user1Secret); - byte[] pubKey = c.getPublic(privKey); - - byte[] privKey2 = c.makePrivate(user2Secret); - byte[] pubKey2 = c.getPublic(privKey2); - - System.out.println("'user1' privKey = " + bytesToHex(privKey)); - System.out.println("'user1' pubKey = " + bytesToHex(pubKey)); - System.out.println("==================================================="); - - System.out.println("'user2' privKey = " + bytesToHex(privKey2)); - System.out.println("'user2' pubKey = " + bytesToHex(pubKey2)); - System.out.println("==================================================="); - - - byte[] ss1 = c.makeSharedSecret(privKey, pubKey2); - System.out.println("'user1' computes shared secret: " + bytesToHex(ss1)); - - byte[] ss2 = c.makeSharedSecret(privKey2, pubKey); - System.out.println("'user2' computes shared secret: " + bytesToHex(ss2)); - - } -} diff --git a/lib/curve25519-donna/contrib/make-snippets b/lib/curve25519-donna/contrib/make-snippets deleted file mode 100644 index 4568721..0000000 --- a/lib/curve25519-donna/contrib/make-snippets +++ /dev/null @@ -1,68 +0,0 @@ -CFLAGS=-Wmissing-prototypes -Wdeclaration-after-statement -O2 -Wall -CC=clang - - -targets: curve25519-donna.a curve25519-donna-c64.a - -test: test-donna test-donna-c64 - - -clean: - rm -f java-src/*.class java-src/*.jnilib *.dylib *.o *.a *.pp test-curve25519-donna test-curve25519-donna-c64 speed-curve25519-donna speed-curve25519-donna-c64 - -curve25519-donna.a: curve25519-donna.o - ar -rc curve25519-donna.a curve25519-donna.o - ranlib curve25519-donna.a - - -##### OSX dynamic library (32- & 64-bit) - -curve25519donna.dylib: curve25519-donna.a curve25519-donna-c64.a - $(CC) -m32 -fpic -shared -Wl,-all_load curve25519-donna.a -Wl,-all_load -o libcurve25519donna.dylib - $(CC) -fpic -shared -Wl,-all_load curve25519-donna-c64.a -Wl,-all_load -o libcurve25519donna_64.dylib - -##### OSX/Java section hence - -# Java JNI - compiled for OSX (32- & 64-bit) -Curve25519Donna.class: - cd java-src; javah -jni Curve25519Donna; cd .. - cd java-src; javac Curve25519Donna.java; cd .. - -Curve25519Donna.jnilib: curve25519-donna.a curve25519-donna-c64.a Curve25519Donna.class - @echo "Building 32-bit..." - clang -o java-src/libCurve25519Donna.jnilib $(CFLAGS) -lc -shared -m32 -I /System/Library/Frameworks/JavaVM.framework/Headers curve25519-donna.o java-src/Curve25519Donna.c - @echo "Building 64-bit..." - clang -o java-src/libCurve25519Donna_64.jnilib $(CFLAGS) -lc -shared -I /System/Library/Frameworks/JavaVM.framework/Headers curve25519-donna-c64.o java-src/Curve25519Donna.c - -##### OSX/Java section end - -curve25519-donna.o: curve25519-donna.c - $(CC) -c curve25519-donna.c $(CFLAGS) -m32 - -curve25519-donna-c64.a: curve25519-donna-c64.o - ar -rc curve25519-donna-c64.a curve25519-donna-c64.o - ranlib curve25519-donna-c64.a - -curve25519-donna-c64.o: curve25519-donna-c64.c - $(CC) -c curve25519-donna-c64.c $(CFLAGS) - -test-donna: test-curve25519-donna - ./test-curve25519-donna | head -123456 | tail -1 - -test-donna-c64: test-curve25519-donna-c64 - ./test-curve25519-donna-c64 | head -123456 | tail -1 - -test-curve25519-donna: test-curve25519.c curve25519-donna.a - $(CC) -o test-curve25519-donna test-curve25519.c curve25519-donna.a $(CFLAGS) -m32 - -test-curve25519-donna-c64: test-curve25519.c curve25519-donna-c64.a - $(CC) -o test-curve25519-donna-c64 test-curve25519.c curve25519-donna-c64.a $(CFLAGS) - -speed-curve25519-donna: speed-curve25519.c curve25519-donna.a - $(CC) -o speed-curve25519-donna speed-curve25519.c curve25519-donna.a $(CFLAGS) -m32 - -speed-curve25519-donna-c64: speed-curve25519.c curve25519-donna-c64.a - $(CC) -o speed-curve25519-donna-c64 speed-curve25519.c curve25519-donna-c64.a $(CFLAGS) - -test-sc-curve25519-donna-c64: test-sc-curve25519.c curve25519-donna-c64.a - $(CC) -o test-sc-curve25519-donna-c64 -O test-sc-curve25519.c curve25519-donna-c64.a test-sc-curve25519.s $(CFLAGS) diff --git a/lib/curve25519-donna/project.conf b/lib/curve25519-donna/project.conf new file mode 100644 index 0000000..5ed7b82 --- /dev/null +++ b/lib/curve25519-donna/project.conf @@ -0,0 +1,5 @@ +[package] +name = "curve25519-donna" +type = "static" +version = "0.1.0" +platforms = ["any"] diff --git a/lib/curve25519-donna/python-src/curve25519/__init__.py b/lib/curve25519-donna/python-src/curve25519/__init__.py deleted file mode 100644 index 873ff57..0000000 --- a/lib/curve25519-donna/python-src/curve25519/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ - -from .keys import Private, Public - -hush_pyflakes = [Private, Public]; del hush_pyflakes diff --git a/lib/curve25519-donna/python-src/curve25519/curve25519module.c b/lib/curve25519-donna/python-src/curve25519/curve25519module.c deleted file mode 100644 index e309ec0..0000000 --- a/lib/curve25519-donna/python-src/curve25519/curve25519module.c +++ /dev/null @@ -1,105 +0,0 @@ -/* tell python that PyArg_ParseTuple(t#) means Py_ssize_t, not int */ -#define PY_SSIZE_T_CLEAN -#include <Python.h> -#if (PY_VERSION_HEX < 0x02050000) - typedef int Py_ssize_t; -#endif - -/* This is required for compatibility with Python 2. */ -#if PY_MAJOR_VERSION >= 3 - #include <bytesobject.h> - #define y "y" -#else - #define PyBytes_FromStringAndSize PyString_FromStringAndSize - #define y "t" -#endif - -int curve25519_donna(char *mypublic, - const char *secret, const char *basepoint); - -static PyObject * -pycurve25519_makeprivate(PyObject *self, PyObject *args) -{ - char *in1; - Py_ssize_t in1len; - if (!PyArg_ParseTuple(args, y"#:clamp", &in1, &in1len)) - return NULL; - if (in1len != 32) { - PyErr_SetString(PyExc_ValueError, "input must be 32-byte string"); - return NULL; - } - in1[0] &= 248; - in1[31] &= 127; - in1[31] |= 64; - return PyBytes_FromStringAndSize((char *)in1, 32); -} - -static PyObject * -pycurve25519_makepublic(PyObject *self, PyObject *args) -{ - const char *private; - char mypublic[32]; - char basepoint[32] = {9}; - Py_ssize_t privatelen; - if (!PyArg_ParseTuple(args, y"#:makepublic", &private, &privatelen)) - return NULL; - if (privatelen != 32) { - PyErr_SetString(PyExc_ValueError, "input must be 32-byte string"); - return NULL; - } - curve25519_donna(mypublic, private, basepoint); - return PyBytes_FromStringAndSize((char *)mypublic, 32); -} - -static PyObject * -pycurve25519_makeshared(PyObject *self, PyObject *args) -{ - const char *myprivate, *theirpublic; - char shared_key[32]; - Py_ssize_t myprivatelen, theirpubliclen; - if (!PyArg_ParseTuple(args, y"#"y"#:generate", - &myprivate, &myprivatelen, &theirpublic, &theirpubliclen)) - return NULL; - if (myprivatelen != 32) { - PyErr_SetString(PyExc_ValueError, "input must be 32-byte string"); - return NULL; - } - if (theirpubliclen != 32) { - PyErr_SetString(PyExc_ValueError, "input must be 32-byte string"); - return NULL; - } - curve25519_donna(shared_key, myprivate, theirpublic); - return PyBytes_FromStringAndSize((char *)shared_key, 32); -} - - -static PyMethodDef -curve25519_functions[] = { - {"make_private", pycurve25519_makeprivate, METH_VARARGS, "data->private"}, - {"make_public", pycurve25519_makepublic, METH_VARARGS, "private->public"}, - {"make_shared", pycurve25519_makeshared, METH_VARARGS, "private+public->shared"}, - {NULL, NULL, 0, NULL}, -}; - -#if PY_MAJOR_VERSION >= 3 - static struct PyModuleDef - curve25519_module = { - PyModuleDef_HEAD_INIT, - "_curve25519", - NULL, - NULL, - curve25519_functions, - }; - - PyObject * - PyInit__curve25519(void) - { - return PyModule_Create(&curve25519_module); - } -#else - PyMODINIT_FUNC - init_curve25519(void) - { - (void)Py_InitModule("_curve25519", curve25519_functions); - } -#endif
\ No newline at end of file diff --git a/lib/curve25519-donna/python-src/curve25519/keys.py b/lib/curve25519-donna/python-src/curve25519/keys.py deleted file mode 100644 index e131dac..0000000 --- a/lib/curve25519-donna/python-src/curve25519/keys.py +++ /dev/null @@ -1,46 +0,0 @@ -from . import _curve25519 -from hashlib import sha256 -import os - -# the curve25519 functions are really simple, and could be used without an -# OOP layer, but it's a bit too easy to accidentally swap the private and -# public keys that way. - -def _hash_shared(shared): - return sha256(b"curve25519-shared:"+shared).digest() - -class Private: - def __init__(self, secret=None, seed=None): - if secret is None: - if seed is None: - secret = os.urandom(32) - else: - secret = sha256(b"curve25519-private:"+seed).digest() - else: - assert seed is None, "provide secret, seed, or neither, not both" - if not isinstance(secret, bytes) or len(secret) != 32: - raise TypeError("secret= must be 32-byte string") - self.private = _curve25519.make_private(secret) - - def serialize(self): - return self.private - - def get_public(self): - return Public(_curve25519.make_public(self.private)) - - def get_shared_key(self, public, hashfunc=None): - if not isinstance(public, Public): - raise ValueError("'public' must be an instance of Public") - if hashfunc is None: - hashfunc = _hash_shared - shared = _curve25519.make_shared(self.private, public.public) - return hashfunc(shared) - -class Public: - def __init__(self, public): - assert isinstance(public, bytes) - assert len(public) == 32 - self.public = public - - def serialize(self): - return self.public diff --git a/lib/curve25519-donna/python-src/curve25519/test/__init__.py b/lib/curve25519-donna/python-src/curve25519/test/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/lib/curve25519-donna/python-src/curve25519/test/__init__.py +++ /dev/null diff --git a/lib/curve25519-donna/python-src/curve25519/test/test_curve25519.py b/lib/curve25519-donna/python-src/curve25519/test/test_curve25519.py deleted file mode 100755 index b3a5447..0000000 --- a/lib/curve25519-donna/python-src/curve25519/test/test_curve25519.py +++ /dev/null @@ -1,99 +0,0 @@ -#! /usr/bin/env python - -import unittest - -from curve25519 import Private, Public -from hashlib import sha1, sha256 -from binascii import hexlify - -class Basic(unittest.TestCase): - def test_basic(self): - secret1 = b"abcdefghijklmnopqrstuvwxyz123456" - self.assertEqual(len(secret1), 32) - - secret2 = b"654321zyxwvutsrqponmlkjihgfedcba" - self.assertEqual(len(secret2), 32) - priv1 = Private(secret=secret1) - pub1 = priv1.get_public() - priv2 = Private(secret=secret2) - pub2 = priv2.get_public() - shared12 = priv1.get_shared_key(pub2) - e = b"b0818125eab42a8ac1af5e8b9b9c15ed2605c2bbe9675de89e5e6e7f442b9598" - self.assertEqual(hexlify(shared12), e) - shared21 = priv2.get_shared_key(pub1) - self.assertEqual(shared12, shared21) - - pub2a = Public(pub2.serialize()) - shared12a = priv1.get_shared_key(pub2a) - self.assertEqual(hexlify(shared12a), e) - - def test_errors(self): - priv1 = Private() - self.assertRaises(ValueError, priv1.get_shared_key, priv1) - - def test_seed(self): - # use 32-byte secret - self.assertRaises(TypeError, Private, secret=123) - self.assertRaises(TypeError, Private, secret=b"too short") - secret1 = b"abcdefghijklmnopqrstuvwxyz123456" - assert len(secret1) == 32 - priv1 = Private(secret=secret1) - priv1a = Private(secret=secret1) - priv1b = Private(priv1.serialize()) - self.assertEqual(priv1.serialize(), priv1a.serialize()) - self.assertEqual(priv1.serialize(), priv1b.serialize()) - e = b"6062636465666768696a6b6c6d6e6f707172737475767778797a313233343576" - self.assertEqual(hexlify(priv1.serialize()), e) - - # the private key is a clamped form of the secret, so they won't - # quite be the same - p = Private(secret=b"\x00"*32) - self.assertEqual(hexlify(p.serialize()), b"00"*31+b"40") - p = Private(secret=b"\xff"*32) - self.assertEqual(hexlify(p.serialize()), b"f8"+b"ff"*30+b"7f") - - # use arbitrary-length seed - self.assertRaises(TypeError, Private, seed=123) - priv1 = Private(seed=b"abc") - priv1a = Private(seed=b"abc") - priv1b = Private(priv1.serialize()) - self.assertEqual(priv1.serialize(), priv1a.serialize()) - self.assertEqual(priv1.serialize(), priv1b.serialize()) - self.assertRaises(AssertionError, Private, seed=b"abc", secret=b"no") - - priv1 = Private(seed=b"abc") - priv1a = Private(priv1.serialize()) - self.assertEqual(priv1.serialize(), priv1a.serialize()) - self.assertRaises(AssertionError, Private, seed=b"abc", secret=b"no") - - # use built-in os.urandom - priv2 = Private() - priv2a = Private(priv2.private) - self.assertEqual(priv2.serialize(), priv2a.serialize()) - - # attempt to use both secret= and seed=, not allowed - self.assertRaises(AssertionError, Private, seed=b"abc", secret=b"no") - - def test_hashfunc(self): - priv1 = Private(seed=b"abc") - priv2 = Private(seed=b"def") - shared_sha256 = priv1.get_shared_key(priv2.get_public()) - e = b"da959ffe77ebeb4757fe5ba310e28ede425ae0d0ff5ec9c884e2d08f311cf5e5" - self.assertEqual(hexlify(shared_sha256), e) - - # confirm the hash function remains what we think it is - def myhash(shared_key): - return sha256(b"curve25519-shared:"+shared_key).digest() - shared_myhash = priv1.get_shared_key(priv2.get_public(), myhash) - self.assertEqual(hexlify(shared_myhash), e) - - def hexhash(shared_key): - return sha1(shared_key).hexdigest().encode() - shared_hexhash = priv1.get_shared_key(priv2.get_public(), hexhash) - self.assertEqual(shared_hexhash, - b"80eec98222c8edc4324fb9477a3c775ce7c6c93a") - - -if __name__ == "__main__": - unittest.main() - diff --git a/lib/curve25519-donna/python-src/curve25519/test/test_speed.py b/lib/curve25519-donna/python-src/curve25519/test/test_speed.py deleted file mode 100755 index 4d7e0c8..0000000 --- a/lib/curve25519-donna/python-src/curve25519/test/test_speed.py +++ /dev/null @@ -1,46 +0,0 @@ -#! /usr/bin/env python - -from time import time -from curve25519 import Private - -count = 10000 -elapsed_get_public = 0.0 -elapsed_get_shared = 0.0 - -def abbreviate_time(data): - # 1.23s, 790ms, 132us - if data is None: - return "" - s = float(data) - if s >= 10: - #return abbreviate.abbreviate_time(data) - return "%d" % s - if s >= 1.0: - return "%.2fs" % s - if s >= 0.01: - return "%dms" % (1000*s) - if s >= 0.001: - return "%.1fms" % (1000*s) - if s >= 0.000001: - return "%.1fus" % (1000000*s) - return "%dns" % (1000000000*s) - -def nohash(key): return key - -for i in range(count): - p = Private() - start = time() - pub = p.get_public() - elapsed_get_public += time() - start - pub2 = Private().get_public() - start = time() - shared = p.get_shared_key(pub2) #, hashfunc=nohash) - elapsed_get_shared += time() - start - -print("get_public: %s" % abbreviate_time(elapsed_get_public / count)) -print("get_shared: %s" % abbreviate_time(elapsed_get_shared / count)) - -# these take about 560us-570us each (with the default compiler settings, -Os) -# on my laptop, same with -O2 -# of which the python overhead is about 5us -# and the get_shared_key() hash step adds about 5us diff --git a/lib/curve25519-donna/test-curve25519.c b/lib/curve25519-donna/test-curve25519.c deleted file mode 100644 index 591d871..0000000 --- a/lib/curve25519-donna/test-curve25519.c +++ /dev/null @@ -1,54 +0,0 @@ -/* -test-curve25519 version 20050915 -D. J. Bernstein -Public domain. - -Tiny modifications by agl -*/ - -#include <stdio.h> - -extern void curve25519_donna(unsigned char *output, const unsigned char *a, - const unsigned char *b); -void doit(unsigned char *ek,unsigned char *e,unsigned char *k); - -void doit(unsigned char *ek,unsigned char *e,unsigned char *k) -{ - int i; - - for (i = 0;i < 32;++i) printf("%02x",(unsigned int) e[i]); printf(" "); - for (i = 0;i < 32;++i) printf("%02x",(unsigned int) k[i]); printf(" "); - curve25519_donna(ek,e,k); - for (i = 0;i < 32;++i) printf("%02x",(unsigned int) ek[i]); printf("\n"); -} - -unsigned char e1k[32]; -unsigned char e2k[32]; -unsigned char e1e2k[32]; -unsigned char e2e1k[32]; -unsigned char e1[32] = {3}; -unsigned char e2[32] = {5}; -unsigned char k[32] = {9}; - -int -main() -{ - int loop; - int i; - - for (loop = 0;loop < 10000;++loop) { - doit(e1k,e1,k); - doit(e2e1k,e2,e1k); - doit(e2k,e2,k); - doit(e1e2k,e1,e2k); - for (i = 0;i < 32;++i) if (e1e2k[i] != e2e1k[i]) { - printf("fail\n"); - return 1; - } - for (i = 0;i < 32;++i) e1[i] ^= e2k[i]; - for (i = 0;i < 32;++i) e2[i] ^= e1k[i]; - for (i = 0;i < 32;++i) k[i] ^= e1e2k[i]; - } - - return 0; -} diff --git a/lib/curve25519-donna/test-noncanon.c b/lib/curve25519-donna/test-noncanon.c deleted file mode 100644 index 6de4e8d..0000000 --- a/lib/curve25519-donna/test-noncanon.c +++ /dev/null @@ -1,39 +0,0 @@ -/* This file can be used to test whether the code handles non-canonical curve - * points (i.e. points with the 256th bit set) in the same way as the reference - * implementation. */ - -#include <stdint.h> -#include <stdio.h> -#include <string.h> - -extern void curve25519_donna(unsigned char *output, const unsigned char *a, - const unsigned char *b); -int -main() -{ - static const uint8_t point1[32] = { - 0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - }; - static const uint8_t point2[32] = { - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - }; - static const uint8_t scalar[32] = { 1 }; - uint8_t out1[32], out2[32]; - - curve25519_donna(out1, scalar, point1); - curve25519_donna(out2, scalar, point2); - - if (0 == memcmp(out1, out2, sizeof(out1))) { - fprintf(stderr, "Top bit not ignored.\n"); - return 1; - } - - fprintf(stderr, "Top bit correctly ignored.\n"); - return 0; -} diff --git a/lib/curve25519-donna/test-sc-curve25519.c b/lib/curve25519-donna/test-sc-curve25519.c deleted file mode 100644 index 14a7e3c..0000000 --- a/lib/curve25519-donna/test-sc-curve25519.c +++ /dev/null @@ -1,72 +0,0 @@ -#define _GNU_SOURCE - -#include <stdio.h> -#include <string.h> -#include <stdint.h> -#include <math.h> - -extern void curve25519_donna(uint8_t *, const uint8_t *, const uint8_t *); -extern uint64_t tsc_read(); - -int -main(int argc, char **argv) { - uint8_t private_key[32], public[32], peer1[32], peer2[32], output[32]; - static const uint8_t basepoint[32] = {9}; - unsigned i; - uint64_t sum = 0, sum_squares = 0, skipped = 0, mean; - static const unsigned count = 200000; - - memset(private_key, 42, sizeof(private_key)); - - private_key[0] &= 248; - private_key[31] &= 127; - private_key[31] |= 64; - - curve25519_donna(public, private_key, basepoint); - memset(peer1, 0, sizeof(peer1)); - memset(peer2, 255, sizeof(peer2)); - - for (i = 0; i < count; ++i) { - const uint64_t start = tsc_read(); - curve25519_donna(output, peer1, public); - const uint64_t end = tsc_read(); - const uint64_t delta = end - start; - if (delta > 650000) { - // something terrible happened (task switch etc) - skipped++; - continue; - } - sum += delta; - sum_squares += (delta * delta); - } - - mean = sum / ((uint64_t) count); - printf("all 0: mean:%lu sd:%f skipped:%lu\n", - mean, - sqrt((double)(sum_squares/((uint64_t) count) - mean*mean)), - skipped); - - sum = sum_squares = skipped = 0; - - for (i = 0; i < count; ++i) { - const uint64_t start = tsc_read(); - curve25519_donna(output, peer2, public); - const uint64_t end = tsc_read(); - const uint64_t delta = end - start; - if (delta > 650000) { - // something terrible happened (task switch etc) - skipped++; - continue; - } - sum += delta; - sum_squares += (delta * delta); - } - - mean = sum / ((uint64_t) count); - printf("all 1: mean:%lu sd:%f skipped:%lu\n", - mean, - sqrt((double)(sum_squares/((uint64_t) count) - mean*mean)), - skipped); - - return 0; -} diff --git a/lib/curve25519-donna/test-sc-curve25519.s b/lib/curve25519-donna/test-sc-curve25519.s deleted file mode 100644 index 1da4f68..0000000 --- a/lib/curve25519-donna/test-sc-curve25519.s +++ /dev/null @@ -1,8 +0,0 @@ -.text -.globl tsc_read - -tsc_read: -rdtsc -shl $32,%rdx -or %rdx,%rax -ret diff --git a/lib/ed25519/.gitignore b/lib/ed25519/.gitignore new file mode 100644 index 0000000..636c6b9 --- /dev/null +++ b/lib/ed25519/.gitignore @@ -0,0 +1,5 @@ +# Compiled sibs files +sibs-build/ +compile_commands.json +tests/sibs-build/ +tests/compile_commands.json diff --git a/lib/ed25519/project.conf b/lib/ed25519/project.conf new file mode 100644 index 0000000..dafccdb --- /dev/null +++ b/lib/ed25519/project.conf @@ -0,0 +1,5 @@ +[package] +name = "ed25519" +type = "static" +version = "0.1.0" +platforms = ["any"] diff --git a/lib/ed25519/test.c b/lib/ed25519/test.c deleted file mode 100644 index e2159a9..0000000 --- a/lib/ed25519/test.c +++ /dev/null @@ -1,150 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <time.h> - -/* #define ED25519_DLL */ -#include "src/ed25519.h" - -#include "src/ge.h" -#include "src/sc.h" - - -int main() { - unsigned char public_key[32], private_key[64], seed[32], scalar[32]; - unsigned char other_public_key[32], other_private_key[64]; - unsigned char shared_secret[32], other_shared_secret[32]; - unsigned char signature[64]; - - clock_t start; - clock_t end; - int i; - - const unsigned char message[] = "Hello, world!"; - const int message_len = strlen((char*) message); - - /* create a random seed, and a keypair out of that seed */ - ed25519_create_seed(seed); - ed25519_create_keypair(public_key, private_key, seed); - - /* create signature on the message with the keypair */ - ed25519_sign(signature, message, message_len, public_key, private_key); - - /* verify the signature */ - if (ed25519_verify(signature, message, message_len, public_key)) { - printf("valid signature\n"); - } else { - printf("invalid signature\n"); - } - - /* create scalar and add it to the keypair */ - ed25519_create_seed(scalar); - ed25519_add_scalar(public_key, private_key, scalar); - - /* create signature with the new keypair */ - ed25519_sign(signature, message, message_len, public_key, private_key); - - /* verify the signature with the new keypair */ - if (ed25519_verify(signature, message, message_len, public_key)) { - printf("valid signature\n"); - } else { - printf("invalid signature\n"); - } - - /* make a slight adjustment and verify again */ - signature[44] ^= 0x10; - if (ed25519_verify(signature, message, message_len, public_key)) { - printf("did not detect signature change\n"); - } else { - printf("correctly detected signature change\n"); - } - - /* generate two keypairs for testing key exchange */ - ed25519_create_seed(seed); - ed25519_create_keypair(public_key, private_key, seed); - ed25519_create_seed(seed); - ed25519_create_keypair(other_public_key, other_private_key, seed); - - /* create two shared secrets - from both perspectives - and check if they're equal */ - ed25519_key_exchange(shared_secret, other_public_key, private_key); - ed25519_key_exchange(other_shared_secret, public_key, other_private_key); - - for (i = 0; i < 32; ++i) { - if (shared_secret[i] != other_shared_secret[i]) { - printf("key exchange was incorrect\n"); - break; - } - } - - if (i == 32) { - printf("key exchange was correct\n"); - } - - /* test performance */ - printf("testing seed generation performance: "); - start = clock(); - for (i = 0; i < 10000; ++i) { - ed25519_create_seed(seed); - } - end = clock(); - - printf("%fus per seed\n", ((double) ((end - start) * 1000)) / CLOCKS_PER_SEC / i * 1000); - - - printf("testing key generation performance: "); - start = clock(); - for (i = 0; i < 10000; ++i) { - ed25519_create_keypair(public_key, private_key, seed); - } - end = clock(); - - printf("%fus per keypair\n", ((double) ((end - start) * 1000)) / CLOCKS_PER_SEC / i * 1000); - - printf("testing sign performance: "); - start = clock(); - for (i = 0; i < 10000; ++i) { - ed25519_sign(signature, message, message_len, public_key, private_key); - } - end = clock(); - - printf("%fus per signature\n", ((double) ((end - start) * 1000)) / CLOCKS_PER_SEC / i * 1000); - - printf("testing verify performance: "); - start = clock(); - for (i = 0; i < 10000; ++i) { - ed25519_verify(signature, message, message_len, public_key); - } - end = clock(); - - printf("%fus per signature\n", ((double) ((end - start) * 1000)) / CLOCKS_PER_SEC / i * 1000); - - - printf("testing keypair scalar addition performance: "); - start = clock(); - for (i = 0; i < 10000; ++i) { - ed25519_add_scalar(public_key, private_key, scalar); - } - end = clock(); - - printf("%fus per keypair\n", ((double) ((end - start) * 1000)) / CLOCKS_PER_SEC / i * 1000); - - printf("testing public key scalar addition performance: "); - start = clock(); - for (i = 0; i < 10000; ++i) { - ed25519_add_scalar(public_key, NULL, scalar); - } - end = clock(); - - printf("%fus per key\n", ((double) ((end - start) * 1000)) / CLOCKS_PER_SEC / i * 1000); - - printf("testing key exchange performance: "); - start = clock(); - for (i = 0; i < 10000; ++i) { - ed25519_key_exchange(shared_secret, other_public_key, private_key); - } - end = clock(); - - printf("%fus per shared secret\n", ((double) ((end - start) * 1000)) / CLOCKS_PER_SEC / i * 1000); - - return 0; -} diff --git a/project.conf b/project.conf new file mode 100644 index 0000000..1af3090 --- /dev/null +++ b/project.conf @@ -0,0 +1,14 @@ +[package] +name = "olm" +type = "static" +version = "3.2.1" +platforms = ["any"] + +[config] +include_dirs = ["include", "lib"] +expose_include_dirs = ["include"] + +[define] +OLMLIB_VERSION_MAJOR = "3" +OLMLIB_VERSION_MINOR = "2" +OLMLIB_VERSION_PATCH = "1" diff --git a/python/.gitignore b/python/.gitignore deleted file mode 100644 index 1ff9f49..0000000 --- a/python/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -.coverage -.mypy_cache/ -.ropeproject/ -.pytest_cache/ -packages/ -python_olm.egg-info/ -_libolm* -__pycache__ -*.pyc -.hypothesis/ -.tox/ -include/ diff --git a/python/MANIFEST.in b/python/MANIFEST.in deleted file mode 100644 index 824b377..0000000 --- a/python/MANIFEST.in +++ /dev/null @@ -1,5 +0,0 @@ -include include/olm/olm.h -include include/olm/pk.h -include include/olm/sas.h -include Makefile -include olm_build.py diff --git a/python/Makefile b/python/Makefile deleted file mode 100644 index 6bba9cd..0000000 --- a/python/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -all: olm-python2 olm-python3 - -OLM_HEADERS = ../include/olm/olm.h ../include/olm/inbound_group_session.h \ - ../include/olm/outbound_group_session.h \ - -include/olm/olm.h: $(OLM_HEADERS) - mkdir -p include/olm - $(CPP) -I dummy -I ../include -o include/olm/olm.h ../include/olm/olm.h -# add memset to the header so that we can use it to clear buffers - echo 'void *memset(void *s, int c, size_t n);' >> include/olm/olm.h - -include/olm/pk.h: include/olm/olm.h ../include/olm/pk.h - $(CPP) -I dummy -I ../include -o include/olm/pk.h ../include/olm/pk.h - -include/olm/sas.h: include/olm/olm.h ../include/olm/sas.h - $(CPP) -I dummy -I ../include -o include/olm/sas.h ../include/olm/sas.h - -headers: include/olm/olm.h include/olm/pk.h include/olm/sas.h - -olm-python2: headers - DEVELOP=$(DEVELOP) python2 setup.py build - -olm-python3: headers - DEVELOP=$(DEVELOP) python3 setup.py build - -install: install-python2 install-python3 - -install-python2: olm-python2 - python2 setup.py install --skip-build -O1 --root=$(DESTDIR) - -install-python3: olm-python3 - python3 setup.py install --skip-build -O1 --root=$(DESTDIR) - -test: olm-python2 olm-python3 - rm -rf install-temp - mkdir -p install-temp/2 install-temp/3 - PYTHONPATH=install-temp/2 python2 setup.py install --skip-build --install-lib install-temp/2 --install-script install-temp/bin - PYTHONPATH=install-temp/3 python3 setup.py install --skip-build --install-lib install-temp/3 --install-script install-temp/bin - PYTHONPATH=install-temp/3 python3 -m pytest - PYTHONPATH=install-temp/2 python2 -m pytest - PYTHONPATH=install-temp/3 python3 -m pytest --flake8 --benchmark-disable - PYTHONPATH=install-temp/3 python3 -m pytest --isort --benchmark-disable - PYTHONPATH=install-temp/3 python3 -m pytest --cov --cov-branch --benchmark-disable - rm -rf install-temp - -isort: - isort -y -p olm - -clean: - rm -rf python_olm.egg-info/ dist/ __pycache__/ - rm -rf *.so _libolm.o - rm -rf packages/ - rm -rf build/ - rm -rf install-temp/ - rm -rf include/ - -.PHONY: all olm-python2 olm-python3 install install-python2 install-python3 clean test diff --git a/python/README.md b/python/README.md deleted file mode 100644 index b928185..0000000 --- a/python/README.md +++ /dev/null @@ -1,161 +0,0 @@ -python-olm -========== - -Python bindings for Olm. - -The specification of the Olm cryptographic ratchet which is used for peer to -peer sessions of this library can be found [here][4]. - -The specification of the Megolm cryptographic ratchet which is used for group -sessions of this library can be found [here][5]. - -An example of the implementation of the Olm and Megolm cryptographic protocol -can be found in the Matrix protocol for which the implementation guide can be -found [here][6]. - -The full API reference can be found [here][7]. - -# Accounts - -Accounts create and hold the central identity of the Olm protocol, they consist of a fingerprint and identity -key pair. They also produce one time keys that are used to start peer to peer -encrypted communication channels. - -## Account Creation - -A new account is created with the Account class, it creates a new Olm key pair. -The public parts of the key pair are available using the identity_keys property -of the class. - -```python ->>> alice = Account() ->>> alice.identity_keys -{'curve25519': '2PytGagXercwHjzQETLcMa3JOsaU2qkPIESaqoi59zE', - 'ed25519': 'HHpOuFYdHwoa54GxSttz9YmaTmbuVU3js92UTUjYJgM'} -``` - - -## One Time keys - -One time keys need to be generated before people can start an encrypted peer to -peer channel to an account. - -```python ->>> alice.generate_one_time_keys(1) ->>> alice.one_time_keys -{'curve25519': {'AAAAAQ': 'KiHoW6CIy905UC4V1Frmwr3VW8bTWkBL4uWtWFFllxM'}} -``` - -After the one time keys are published they should be marked as such so they -aren't reused. - -```python ->>> alice.mark_keys_as_published() ->>> alice.one_time_keys -{'curve25519': {}} -``` - -## Pickling - -Accounts should be stored for later reuse, storing an account is done with the -pickle method while the restoring step is done with the from_pickle class -method. - -```python ->>> pickle = alice.pickle() ->>> restored = Account.from_pickle(pickle) -``` - -# Sessions - -Sessions are used to create an encrypted peer to peer communication channel -between two accounts. - -## Session Creation -```python ->>> alice = Account() ->>> bob = Account() ->>> bob.generate_one_time_keys(1) ->>> id_key = bob.identity_keys["curve25519"] ->>> one_time = list(bob.one_time_keys["curve25519"].values())[0] ->>> alice_session = OutboundSession(alice, id_key, one_time) -``` - -## Encryption - -After an outbound session is created an encrypted message can be exchanged: - -```python ->>> message = alice_session.encrypt("It's a secret to everybody") ->>> message.ciphertext -'AwogkL7RoakT9gnjcZMra+y39WXKRmnxBPEaEp6OSueIA0cSIJxGpBoP8YZ+CGweXQ10LujbXMgK88 -xG/JZMQJ5ulK9ZGiC8TYrezNYr3qyIBLlecXr/9wnegvJaSFDmWDVOcf4XfyI/AwogqIZfAklRXGC5b -ZJcZxVxQGgJ8Dz4OQII8k0Dp8msUXwQACIQvagY1dO55Qvnk5PZ2GF+wdKnvj6Zxl2g' ->>> message.message_type -0 -``` - -After the message is transfered, bob can create an InboundSession to decrypt the -message. - -```python ->>> bob_session = InboundSession(bob, message) ->>> bob_session.decrypt(message) -"It's a secret to everybody" -``` - -## Pickling - -Sessions like accounts can be stored for later use the API is the same as for -accounts. - -```python ->>> pickle = session.pickle() ->>> restored = Session.from_pickle(pickle) -``` - -# Group Sessions - -Group Sessions are used to create a one-to-many encrypted communication channel. -The group session key needs to be shared with all participants that should be able -to decrypt the group messages. Another thing to notice is that, since the group -session key is ratcheted every time a message is encrypted, the session key should -be shared before any messages are encrypted. - -## Group Session Creation - -Group sessions aren't bound to an account like peer-to-peer sessions so their -creation is straightforward. - -```python ->>> alice_group = OutboundGroupSession() ->>> bob_inbound_group = InboundGroupSession(alice_group.session_key) -``` - -## Group Encryption - -Group encryption is pretty simple. The important part is to share the session -key with all participants over a secure channel (e.g. peer-to-peer Olm -sessions). - -```python ->>> message = alice_group.encrypt("It's a secret to everybody") ->>> bob_inbound_group.decrypt(message) -("It's a secret to everybody", 0) -``` - -## Pickling - -Pickling works the same way as for peer-to-peer Olm sessions. - -```python ->>> pickle = session.pickle() ->>> restored = InboundGroupSession.from_pickle(pickle) -``` -[1]: https://git.matrix.org/git/olm/about/ -[2]: https://git.matrix.org/git/olm/tree/python?id=f8c61b8f8432d0b0b38d57f513c5048fb42f22ab -[3]: https://cffi.readthedocs.io/en/latest/ -[4]: https://git.matrix.org/git/olm/about/docs/olm.rst -[5]: https://git.matrix.org/git/olm/about/docs/megolm.rst -[6]: https://matrix.org/docs/guides/e2e_implementation.html -[7]: https://poljar.github.io/python-olm/html/index.html diff --git a/python/docs/Makefile b/python/docs/Makefile deleted file mode 100644 index a72f9d9..0000000 --- a/python/docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -SPHINXPROJ = olm -SOURCEDIR = . -BUILDDIR = . - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/python/docs/conf.py b/python/docs/conf.py deleted file mode 100644 index ce2a88d..0000000 --- a/python/docs/conf.py +++ /dev/null @@ -1,165 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Configuration file for the Sphinx documentation builder. -# -# This file does only contain a selection of the most common options. For a -# full list see the documentation: -# http://www.sphinx-doc.org/en/master/config - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -import os -import sys - -sys.path.insert(0, os.path.abspath('../')) - - -# -- Project information ----------------------------------------------------- - -project = 'python-olm' -copyright = '2018, Damir Jelić' -author = 'Damir Jelić' - -# The short X.Y version -version = '' -# The full version, including alpha/beta/rc tags -release = '2.2' - - -# -- General configuration --------------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -# -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.doctest', - 'sphinx.ext.coverage', - 'sphinx.ext.viewcode', - 'sphinx.ext.githubpages', - 'sphinx.ext.napoleon', -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The master toctree document. -master_doc = 'index' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path . -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = 'alabaster' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# -# html_theme_options = {} - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Custom sidebar templates, must be a dictionary that maps document names -# to template names. -# -# The default sidebars (for documents that don't match any pattern) are -# defined by theme itself. Builtin themes are using these templates by -# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', -# 'searchbox.html']``. -# -# html_sidebars = {} - - -# -- Options for HTMLHelp output --------------------------------------------- - -# Output file base name for HTML help builder. -htmlhelp_basename = 'olmdoc' - - -# -- Options for LaTeX output ------------------------------------------------ - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'olm.tex', 'olm Documentation', - 'Damir Jelić', 'manual'), -] - - -# -- Options for manual page output ------------------------------------------ - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'olm', 'olm Documentation', - [author], 1) -] - - -# -- Options for Texinfo output ---------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'olm', 'olm Documentation', - author, 'olm', 'One line description of project.', - 'Miscellaneous'), -] - - -# -- Extension configuration ------------------------------------------------- diff --git a/python/docs/index.html b/python/docs/index.html deleted file mode 100644 index 9644bbb..0000000 --- a/python/docs/index.html +++ /dev/null @@ -1 +0,0 @@ -<meta http-equiv="refresh" content="0; url=./html/index.html" /> diff --git a/python/docs/index.rst b/python/docs/index.rst deleted file mode 100644 index 39e6657..0000000 --- a/python/docs/index.rst +++ /dev/null @@ -1,19 +0,0 @@ -.. olm documentation master file, created by - sphinx-quickstart on Sun Jun 17 15:57:08 2018. - -Welcome to olm's documentation! -=============================== - -.. toctree:: - Olm API reference <olm.rst> - :maxdepth: 2 - :caption: Contents: - - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/python/docs/make.bat b/python/docs/make.bat deleted file mode 100644 index 1c5b4d8..0000000 --- a/python/docs/make.bat +++ /dev/null @@ -1,36 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build -set SPHINXPROJ=olm - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% - -:end -popd diff --git a/python/docs/olm.rst b/python/docs/olm.rst deleted file mode 100644 index 9d8edf0..0000000 --- a/python/docs/olm.rst +++ /dev/null @@ -1,34 +0,0 @@ -olm package -=========== - -olm.account module ------------------- - -.. automodule:: olm.account - :members: - :undoc-members: - :show-inheritance: - -olm.group\_session module -------------------------- - -.. automodule:: olm.group_session - :members: - :undoc-members: - :show-inheritance: - -olm.session module ------------------- - -.. automodule:: olm.session - :members: - :undoc-members: - :show-inheritance: - -olm.utility module ------------------- - -.. automodule:: olm.utility - :members: - :undoc-members: - :show-inheritance: diff --git a/python/dummy/README b/python/dummy/README deleted file mode 100644 index 61039f3..0000000 --- a/python/dummy/README +++ /dev/null @@ -1,2 +0,0 @@ -Dummy header files, so that we can generate the function list for cffi from the -olm header files.
\ No newline at end of file diff --git a/python/dummy/stddef.h b/python/dummy/stddef.h deleted file mode 100644 index e69de29..0000000 --- a/python/dummy/stddef.h +++ /dev/null diff --git a/python/dummy/stdint.h b/python/dummy/stdint.h deleted file mode 100644 index e69de29..0000000 --- a/python/dummy/stdint.h +++ /dev/null diff --git a/python/olm/__init__.py b/python/olm/__init__.py deleted file mode 100644 index 26257a5..0000000 --- a/python/olm/__init__.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -# libolm python bindings -# Copyright © 2015-2017 OpenMarket Ltd -# Copyright © 2018 Damir Jelić <poljar@termina.org.uk> -# -# 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. -""" -Olm Python bindings -~~~~~~~~~~~~~~~~~~~~~ -| This package implements python bindings for the libolm C library. -| © Copyright 2015-2017 by OpenMarket Ltd -| © Copyright 2018 by Damir Jelić -""" -from .utility import ed25519_verify, OlmVerifyError, OlmHashError, sha256 -from .account import Account, OlmAccountError -from .session import ( - Session, - InboundSession, - OutboundSession, - OlmSessionError, - OlmMessage, - OlmPreKeyMessage -) -from .group_session import ( - InboundGroupSession, - OutboundGroupSession, - OlmGroupSessionError -) -from .pk import ( - PkMessage, - PkEncryption, - PkDecryption, - PkSigning, - PkEncryptionError, - PkDecryptionError, - PkSigningError -) -from .sas import Sas, OlmSasError diff --git a/python/olm/__version__.py b/python/olm/__version__.py deleted file mode 100644 index 498f89f..0000000 --- a/python/olm/__version__.py +++ /dev/null @@ -1,9 +0,0 @@ -__title__ = "python-olm" -__description__ = ("python CFFI bindings for the olm " - "cryptographic ratchet library") -__url__ = "https://github.com/poljar/python-olm" -__version__ = "3.2.1" -__author__ = "Damir Jelić" -__author_email__ = "poljar@termina.org.uk" -__license__ = "Apache 2.0" -__copyright__ = "Copyright 2018-2019 Damir Jelić" diff --git a/python/olm/_compat.py b/python/olm/_compat.py deleted file mode 100644 index 2ceaa33..0000000 --- a/python/olm/_compat.py +++ /dev/null @@ -1,67 +0,0 @@ -# -*- coding: utf-8 -*- -# libolm python bindings -# Copyright © 2015-2017 OpenMarket Ltd -# Copyright © 2018 Damir Jelić <poljar@termina.org.uk> -# -# 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. - -from builtins import bytes, str -from typing import AnyStr - -try: - import secrets - URANDOM = secrets.token_bytes # pragma: no cover -except ImportError: # pragma: no cover - from os import urandom - URANDOM = urandom # type: ignore - - -def to_bytearray(string): - # type: (AnyStr) -> bytes - if isinstance(string, bytes): - return bytearray(string) - elif isinstance(string, str): - return bytearray(string, "utf-8") - - raise TypeError("Invalid type {}".format(type(string))) - - -def to_bytes(string): - # type: (AnyStr) -> bytes - if isinstance(string, bytes): - return string - elif isinstance(string, str): - return bytes(string, "utf-8") - - raise TypeError("Invalid type {}".format(type(string))) - - -def to_unicode_str(byte_string, errors="replace"): - """Turn a byte string into a unicode string. - - Should be used everywhere where the input byte string might not be trusted - and may contain invalid unicode values. - - Args: - byte_string (bytes): The bytestring that will be converted to a native - string. - errors (str, optional): The error handling scheme that should be used - to handle unicode decode errors. Can be one of "strict" (raise an - UnicodeDecodeError exception, "ignore" (remove the offending - characters), "replace" (replace the offending character with - U+FFFD), "xmlcharrefreplace" as well as any other name registered - with codecs.register_error that can handle UnicodeEncodeErrors. - - Returns the decoded native string. - """ - return byte_string.decode(encoding="utf-8", errors=errors) diff --git a/python/olm/_finalize.py b/python/olm/_finalize.py deleted file mode 100644 index 9f467bc..0000000 --- a/python/olm/_finalize.py +++ /dev/null @@ -1,65 +0,0 @@ -# The MIT License (MIT) -# Copyright (c) 2010 Benjamin Peterson <benjamin@python.org> - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -# OR OTHER DEALINGS IN THE SOFTWARE. - -"""Finalization with weakrefs - -This is designed for avoiding __del__. -""" -from __future__ import print_function - -import sys -import traceback -import weakref - -__author__ = "Benjamin Peterson <benjamin@python.org>" - - -class OwnerRef(weakref.ref): - """A simple weakref.ref subclass, so attributes can be added.""" - pass - - -def _run_finalizer(ref): - """Internal weakref callback to run finalizers""" - del _finalize_refs[id(ref)] - finalizer = ref.finalizer - item = ref.item - try: - finalizer(item) - except Exception: # pragma: no cover - print("Exception running {}:".format(finalizer), file=sys.stderr) - traceback.print_exc() - - -_finalize_refs = {} - - -def track_for_finalization(owner, item, finalizer): - """Register an object for finalization. - - ``owner`` is the the object which is responsible for ``item``. - ``finalizer`` will be called with ``item`` as its only argument when - ``owner`` is destroyed by the garbage collector. - """ - ref = OwnerRef(owner, _run_finalizer) - ref.item = item - ref.finalizer = finalizer - _finalize_refs[id(ref)] = ref diff --git a/python/olm/account.py b/python/olm/account.py deleted file mode 100644 index 8455655..0000000 --- a/python/olm/account.py +++ /dev/null @@ -1,271 +0,0 @@ -# -*- coding: utf-8 -*- -# libolm python bindings -# Copyright © 2015-2017 OpenMarket Ltd -# Copyright © 2018 Damir Jelić <poljar@termina.org.uk> -# -# 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. -"""libolm Account module. - -This module contains the account part of the Olm library. It contains a single -Account class which handles the creation of new accounts as well as the storing -and restoring of them. - -Examples: - >>> acc = Account() - >>> account.identity_keys() - >>> account.generate_one_time_keys(1) - -""" - -import json -# pylint: disable=redefined-builtin,unused-import -from builtins import bytes, super -from typing import AnyStr, Dict, Optional, Type - -from future.utils import bytes_to_native_str - -# pylint: disable=no-name-in-module -from _libolm import ffi, lib # type: ignore - -from ._compat import URANDOM, to_bytearray -from ._finalize import track_for_finalization - -# This is imported only for type checking purposes -if False: - from .session import Session # pragma: no cover - - -def _clear_account(account): - # type: (ffi.cdata) -> None - lib.olm_clear_account(account) - - -class OlmAccountError(Exception): - """libolm Account error exception.""" - - -class Account(object): - """libolm Account class.""" - - def __new__(cls): - # type: (Type[Account]) -> Account - obj = super().__new__(cls) - obj._buf = ffi.new("char[]", lib.olm_account_size()) - obj._account = lib.olm_account(obj._buf) - track_for_finalization(obj, obj._account, _clear_account) - return obj - - def __init__(self): - # type: () -> None - """Create a new Olm account. - - Creates a new account and its matching identity key pair. - - Raises OlmAccountError on failure. If there weren't enough random bytes - for the account creation the error message for the exception will be - NOT_ENOUGH_RANDOM. - """ - # This is needed to silence mypy not knowing the type of _account. - # There has to be a better way for this. - if False: # pragma: no cover - self._account = self._account # type: ffi.cdata - - random_length = lib.olm_create_account_random_length(self._account) - random = URANDOM(random_length) - - self._check_error( - lib.olm_create_account(self._account, ffi.from_buffer(random), - random_length)) - - - def _check_error(self, ret): - # type: (int) -> None - if ret != lib.olm_error(): - return - - last_error = bytes_to_native_str( - ffi.string((lib.olm_account_last_error(self._account)))) - - raise OlmAccountError(last_error) - - def pickle(self, passphrase=""): - # type: (Optional[str]) -> bytes - """Store an Olm account. - - Stores an account as a base64 string. Encrypts the account using the - supplied passphrase. Returns a byte object containing the base64 - encoded string of the pickled account. Raises OlmAccountError on - failure. - - Args: - passphrase(str, optional): The passphrase to be used to encrypt - the account. - """ - byte_key = bytearray(passphrase, "utf-8") if passphrase else b"" - - pickle_length = lib.olm_pickle_account_length(self._account) - pickle_buffer = ffi.new("char[]", pickle_length) - - try: - self._check_error( - lib.olm_pickle_account(self._account, - ffi.from_buffer(byte_key), - len(byte_key), - pickle_buffer, - pickle_length)) - finally: - # zero out copies of the passphrase - for i in range(0, len(byte_key)): - byte_key[i] = 0 - - return ffi.unpack(pickle_buffer, pickle_length) - - @classmethod - def from_pickle(cls, pickle, passphrase=""): - # type: (bytes, Optional[str]) -> Account - """Load a previously stored olm account. - - Loads an account from a pickled base64-encoded string and returns an - Account object. Decrypts the account using the supplied passphrase. - Raises OlmAccountError on failure. If the passphrase doesn't match the - one used to encrypt the account then the error message for the - exception will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded - then the error message will be "INVALID_BASE64". - - Args: - pickle(bytes): Base64 encoded byte string containing the pickled - account - passphrase(str, optional): The passphrase used to encrypt the - account. - """ - if not pickle: - raise ValueError("Pickle can't be empty") - - byte_key = bytearray(passphrase, "utf-8") if passphrase else b"" - # copy because unpickle will destroy the buffer - pickle_buffer = ffi.new("char[]", pickle) - - obj = cls.__new__(cls) - - try: - ret = lib.olm_unpickle_account(obj._account, - ffi.from_buffer(byte_key), - len(byte_key), - pickle_buffer, - len(pickle)) - obj._check_error(ret) - finally: - for i in range(0, len(byte_key)): - byte_key[i] = 0 - - return obj - - @property - def identity_keys(self): - # type: () -> Dict[str, str] - """dict: Public part of the identity keys of the account.""" - out_length = lib.olm_account_identity_keys_length(self._account) - out_buffer = ffi.new("char[]", out_length) - - self._check_error( - lib.olm_account_identity_keys(self._account, out_buffer, - out_length)) - return json.loads(ffi.unpack(out_buffer, out_length).decode("utf-8")) - - def sign(self, message): - # type: (AnyStr) -> str - """Signs a message with this account. - - Signs a message with the private ed25519 identity key of this account. - Returns the signature. - Raises OlmAccountError on failure. - - Args: - message(str): The message to sign. - """ - bytes_message = to_bytearray(message) - out_length = lib.olm_account_signature_length(self._account) - out_buffer = ffi.new("char[]", out_length) - - try: - self._check_error( - lib.olm_account_sign(self._account, - ffi.from_buffer(bytes_message), - len(bytes_message), out_buffer, - out_length)) - finally: - # clear out copies of the message, which may be plaintext - if bytes_message is not message: - for i in range(0, len(bytes_message)): - bytes_message[i] = 0 - - return bytes_to_native_str(ffi.unpack(out_buffer, out_length)) - - @property - def max_one_time_keys(self): - # type: () -> int - """int: The maximum number of one-time keys the account can store.""" - return lib.olm_account_max_number_of_one_time_keys(self._account) - - def mark_keys_as_published(self): - # type: () -> None - """Mark the current set of one-time keys as being published.""" - lib.olm_account_mark_keys_as_published(self._account) - - def generate_one_time_keys(self, count): - # type: (int) -> None - """Generate a number of new one-time keys. - - If the total number of keys stored by this account exceeds - max_one_time_keys() then the old keys are discarded. - Raises OlmAccountError on error. - - Args: - count(int): The number of keys to generate. - """ - random_length = lib.olm_account_generate_one_time_keys_random_length( - self._account, count) - random = URANDOM(random_length) - - self._check_error( - lib.olm_account_generate_one_time_keys( - self._account, count, ffi.from_buffer(random), random_length)) - - @property - def one_time_keys(self): - # type: () -> Dict[str, Dict[str, str]] - """dict: The public part of the one-time keys for this account.""" - out_length = lib.olm_account_one_time_keys_length(self._account) - out_buffer = ffi.new("char[]", out_length) - - self._check_error( - lib.olm_account_one_time_keys(self._account, out_buffer, - out_length)) - - return json.loads(ffi.unpack(out_buffer, out_length).decode("utf-8")) - - def remove_one_time_keys(self, session): - # type: (Session) -> None - """Remove used one-time keys. - - Removes the one-time keys that the session used from the account. - Raises OlmAccountError on failure. If the account doesn't have any - matching one-time keys then the error message of the exception will be - "BAD_MESSAGE_KEY_ID". - - Args: - session(Session): An Olm Session object that was created with this - account. - """ - self._check_error(lib.olm_remove_one_time_keys(self._account, - session._session)) diff --git a/python/olm/group_session.py b/python/olm/group_session.py deleted file mode 100644 index 5068192..0000000 --- a/python/olm/group_session.py +++ /dev/null @@ -1,532 +0,0 @@ -# -*- coding: utf-8 -*- -# libolm python bindings -# Copyright © 2015-2017 OpenMarket Ltd -# Copyright © 2018 Damir Jelić <poljar@termina.org.uk> -# -# 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. -"""libolm Group session module. - -This module contains the group session part of the Olm library. It contains two -classes for creating inbound and outbound group sessions. - -Examples: - >>> outbound = OutboundGroupSession() - >>> InboundGroupSession(outbound.session_key) -""" - -# pylint: disable=redefined-builtin,unused-import -from builtins import bytes, super -from typing import AnyStr, Optional, Tuple, Type - -from future.utils import bytes_to_native_str - -# pylint: disable=no-name-in-module -from _libolm import ffi, lib # type: ignore - -from ._compat import URANDOM, to_bytearray, to_bytes, to_unicode_str -from ._finalize import track_for_finalization - - -def _clear_inbound_group_session(session): - # type: (ffi.cdata) -> None - lib.olm_clear_inbound_group_session(session) - - -def _clear_outbound_group_session(session): - # type: (ffi.cdata) -> None - lib.olm_clear_outbound_group_session(session) - - -class OlmGroupSessionError(Exception): - """libolm Group session error exception.""" - - -class InboundGroupSession(object): - """Inbound group session for encrypted multiuser communication.""" - - def __new__( - cls, # type: Type[InboundGroupSession] - session_key=None # type: Optional[str] - ): - # type: (...) -> InboundGroupSession - obj = super().__new__(cls) - obj._buf = ffi.new("char[]", lib.olm_inbound_group_session_size()) - obj._session = lib.olm_inbound_group_session(obj._buf) - track_for_finalization(obj, obj._session, _clear_inbound_group_session) - return obj - - def __init__(self, session_key): - # type: (AnyStr) -> None - """Create a new inbound group session. - Start a new inbound group session, from a key exported from - an outbound group session. - - Raises OlmGroupSessionError on failure. The error message of the - exception will be "OLM_INVALID_BASE64" if the session key is not valid - base64 and "OLM_BAD_SESSION_KEY" if the session key is invalid. - """ - if False: # pragma: no cover - self._session = self._session # type: ffi.cdata - - byte_session_key = to_bytearray(session_key) - - try: - ret = lib.olm_init_inbound_group_session( - self._session, - ffi.from_buffer(byte_session_key), len(byte_session_key) - ) - finally: - if byte_session_key is not session_key: - for i in range(0, len(byte_session_key)): - byte_session_key[i] = 0 - self._check_error(ret) - - def pickle(self, passphrase=""): - # type: (Optional[str]) -> bytes - """Store an inbound group session. - - Stores a group session as a base64 string. Encrypts the session using - the supplied passphrase. Returns a byte object containing the base64 - encoded string of the pickled session. - - Args: - passphrase(str, optional): The passphrase to be used to encrypt - the session. - """ - byte_passphrase = bytearray(passphrase, "utf-8") if passphrase else b"" - - pickle_length = lib.olm_pickle_inbound_group_session_length( - self._session) - pickle_buffer = ffi.new("char[]", pickle_length) - - try: - ret = lib.olm_pickle_inbound_group_session( - self._session, - ffi.from_buffer(byte_passphrase), len(byte_passphrase), - pickle_buffer, pickle_length - ) - self._check_error(ret) - finally: - # clear out copies of the passphrase - for i in range(0, len(byte_passphrase)): - byte_passphrase[i] = 0 - - return ffi.unpack(pickle_buffer, pickle_length) - - @classmethod - def from_pickle(cls, pickle, passphrase=""): - # type: (bytes, Optional[str]) -> InboundGroupSession - """Load a previously stored inbound group session. - - Loads an inbound group session from a pickled base64 string and returns - an InboundGroupSession object. Decrypts the session using the supplied - passphrase. Raises OlmSessionError on failure. If the passphrase - doesn't match the one used to encrypt the session then the error - message for the exception will be "BAD_ACCOUNT_KEY". If the base64 - couldn't be decoded then the error message will be "INVALID_BASE64". - - Args: - pickle(bytes): Base64 encoded byte string containing the pickled - session - passphrase(str, optional): The passphrase used to encrypt the - session - """ - if not pickle: - raise ValueError("Pickle can't be empty") - - byte_passphrase = bytearray(passphrase, "utf-8") if passphrase else b"" - # copy because unpickle will destroy the buffer - pickle_buffer = ffi.new("char[]", pickle) - - obj = cls.__new__(cls) - - try: - ret = lib.olm_unpickle_inbound_group_session( - obj._session, - ffi.from_buffer(byte_passphrase), - len(byte_passphrase), - pickle_buffer, - len(pickle) - ) - obj._check_error(ret) - finally: - # clear out copies of the passphrase - for i in range(0, len(byte_passphrase)): - byte_passphrase[i] = 0 - - return obj - - def _check_error(self, ret): - # type: (int) -> None - if ret != lib.olm_error(): - return - - last_error = bytes_to_native_str(ffi.string( - lib.olm_inbound_group_session_last_error(self._session))) - - raise OlmGroupSessionError(last_error) - - def decrypt(self, ciphertext, unicode_errors="replace"): - # type: (AnyStr, str) -> Tuple[str, int] - """Decrypt a message - - Returns a tuple of the decrypted plain-text and the message index of - the decrypted message or raises OlmGroupSessionError on failure. - On failure the error message of the exception will be: - - * OLM_INVALID_BASE64 if the message is not valid base64 - * 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 (i.e., it was sent before - the session key was shared with us) - - Args: - ciphertext(str): Base64 encoded ciphertext containing the encrypted - message - unicode_errors(str, optional): The error handling scheme to use for - unicode decoding errors. The default is "replace" meaning that - the character that was unable to decode will be replaced with - the unicode replacement character (U+FFFD). Other possible - values are "strict", "ignore" and "xmlcharrefreplace" as well - as any other name registered with codecs.register_error that - can handle UnicodeEncodeErrors. - """ - if not ciphertext: - raise ValueError("Ciphertext can't be empty.") - - byte_ciphertext = to_bytes(ciphertext) - - # copy because max_plaintext_length will destroy the buffer - ciphertext_buffer = ffi.new("char[]", byte_ciphertext) - - max_plaintext_length = lib.olm_group_decrypt_max_plaintext_length( - self._session, ciphertext_buffer, len(byte_ciphertext) - ) - self._check_error(max_plaintext_length) - plaintext_buffer = ffi.new("char[]", max_plaintext_length) - # copy because max_plaintext_length will destroy the buffer - ciphertext_buffer = ffi.new("char[]", byte_ciphertext) - - message_index = ffi.new("uint32_t*") - plaintext_length = lib.olm_group_decrypt( - self._session, ciphertext_buffer, len(byte_ciphertext), - plaintext_buffer, max_plaintext_length, - message_index - ) - - self._check_error(plaintext_length) - - plaintext = to_unicode_str( - ffi.unpack(plaintext_buffer, plaintext_length), - errors=unicode_errors - ) - - # clear out copies of the plaintext - lib.memset(plaintext_buffer, 0, max_plaintext_length) - - return plaintext, message_index[0] - - @property - def id(self): - # type: () -> str - """str: A base64 encoded identifier for this session.""" - id_length = lib.olm_inbound_group_session_id_length(self._session) - id_buffer = ffi.new("char[]", id_length) - ret = lib.olm_inbound_group_session_id( - self._session, - id_buffer, - id_length - ) - self._check_error(ret) - return bytes_to_native_str(ffi.unpack(id_buffer, id_length)) - - @property - def first_known_index(self): - # type: () -> int - """int: The first message index we know how to decrypt.""" - return lib.olm_inbound_group_session_first_known_index(self._session) - - def export_session(self, message_index): - # type: (int) -> str - """Export an inbound group session - - Export the base64-encoded ratchet key for this session, at the given - index, in a format which can be used by import_session(). - - Raises OlmGroupSessionError on failure. The error message for the - exception will be: - - * 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) - - Args: - message_index(int): The message index at which the session should - be exported. - """ - - export_length = lib.olm_export_inbound_group_session_length( - self._session) - - export_buffer = ffi.new("char[]", export_length) - ret = lib.olm_export_inbound_group_session( - self._session, - export_buffer, - export_length, - message_index - ) - self._check_error(ret) - export_str = bytes_to_native_str(ffi.unpack(export_buffer, export_length)) - - # clear out copies of the key - lib.memset(export_buffer, 0, export_length) - - return export_str - - @classmethod - def import_session(cls, session_key): - # type: (AnyStr) -> InboundGroupSession - """Create an InboundGroupSession from an exported session key. - - Creates an InboundGroupSession with an previously exported session key, - raises OlmGroupSessionError on failure. The error message for the - exception will be: - - * OLM_INVALID_BASE64 if the session_key is not valid base64 - * OLM_BAD_SESSION_KEY if the session_key is invalid - - Args: - session_key(str): The exported session key with which the inbound - group session will be created - """ - obj = cls.__new__(cls) - - byte_session_key = to_bytearray(session_key) - - try: - ret = lib.olm_import_inbound_group_session( - obj._session, - ffi.from_buffer(byte_session_key), - len(byte_session_key) - ) - obj._check_error(ret) - finally: - # clear out copies of the key - if byte_session_key is not session_key: - for i in range(0, len(byte_session_key)): - byte_session_key[i] = 0 - - return obj - - -class OutboundGroupSession(object): - """Outbound group session for encrypted multiuser communication.""" - - def __new__(cls): - # type: (Type[OutboundGroupSession]) -> OutboundGroupSession - obj = super().__new__(cls) - obj._buf = ffi.new("char[]", lib.olm_outbound_group_session_size()) - obj._session = lib.olm_outbound_group_session(obj._buf) - track_for_finalization( - obj, - obj._session, - _clear_outbound_group_session - ) - return obj - - def __init__(self): - # type: () -> None - """Create a new outbound group session. - - Start a new outbound group session. Raises OlmGroupSessionError on - failure. - """ - if False: # pragma: no cover - self._session = self._session # type: ffi.cdata - - random_length = lib.olm_init_outbound_group_session_random_length( - self._session - ) - random = URANDOM(random_length) - - ret = lib.olm_init_outbound_group_session( - self._session, ffi.from_buffer(random), random_length - ) - self._check_error(ret) - - def _check_error(self, ret): - # type: (int) -> None - if ret != lib.olm_error(): - return - - last_error = bytes_to_native_str(ffi.string( - lib.olm_outbound_group_session_last_error(self._session) - )) - - raise OlmGroupSessionError(last_error) - - def pickle(self, passphrase=""): - # type: (Optional[str]) -> bytes - """Store an outbound group session. - - Stores a group session as a base64 string. Encrypts the session using - the supplied passphrase. Returns a byte object containing the base64 - encoded string of the pickled session. - - Args: - passphrase(str, optional): The passphrase to be used to encrypt - the session. - """ - byte_passphrase = bytearray(passphrase, "utf-8") if passphrase else b"" - pickle_length = lib.olm_pickle_outbound_group_session_length( - self._session) - pickle_buffer = ffi.new("char[]", pickle_length) - - try: - ret = lib.olm_pickle_outbound_group_session( - self._session, - ffi.from_buffer(byte_passphrase), len(byte_passphrase), - pickle_buffer, pickle_length - ) - self._check_error(ret) - finally: - # clear out copies of the passphrase - for i in range(0, len(byte_passphrase)): - byte_passphrase[i] = 0 - - return ffi.unpack(pickle_buffer, pickle_length) - - @classmethod - def from_pickle(cls, pickle, passphrase=""): - # type: (bytes, Optional[str]) -> OutboundGroupSession - """Load a previously stored outbound group session. - - Loads an outbound group session from a pickled base64 string and - returns an OutboundGroupSession object. Decrypts the session using the - supplied passphrase. Raises OlmSessionError on failure. If the - passphrase doesn't match the one used to encrypt the session then the - error message for the exception will be "BAD_ACCOUNT_KEY". If the - base64 couldn't be decoded then the error message will be - "INVALID_BASE64". - - Args: - pickle(bytes): Base64 encoded byte string containing the pickled - session - passphrase(str, optional): The passphrase used to encrypt the - """ - if not pickle: - raise ValueError("Pickle can't be empty") - - byte_passphrase = bytearray(passphrase, "utf-8") if passphrase else b"" - # copy because unpickle will destroy the buffer - pickle_buffer = ffi.new("char[]", pickle) - - obj = cls.__new__(cls) - - try: - ret = lib.olm_unpickle_outbound_group_session( - obj._session, - ffi.from_buffer(byte_passphrase), - len(byte_passphrase), - pickle_buffer, - len(pickle) - ) - obj._check_error(ret) - finally: - # clear out copies of the passphrase - for i in range(0, len(byte_passphrase)): - byte_passphrase[i] = 0 - - return obj - - def encrypt(self, plaintext): - # type: (AnyStr) -> str - """Encrypt a message. - - Returns the encrypted ciphertext. - - Args: - plaintext(str): A string that will be encrypted using the group - session. - """ - byte_plaintext = to_bytearray(plaintext) - message_length = lib.olm_group_encrypt_message_length( - self._session, len(byte_plaintext) - ) - - message_buffer = ffi.new("char[]", message_length) - - try: - ret = lib.olm_group_encrypt( - self._session, - ffi.from_buffer(byte_plaintext), len(byte_plaintext), - message_buffer, message_length, - ) - self._check_error(ret) - finally: - # clear out copies of plaintext - if byte_plaintext is not plaintext: - for i in range(0, len(byte_plaintext)): - byte_plaintext[i] = 0 - - return bytes_to_native_str(ffi.unpack(message_buffer, message_length)) - - @property - def id(self): - # type: () -> str - """str: A base64 encoded identifier for this session.""" - id_length = lib.olm_outbound_group_session_id_length(self._session) - id_buffer = ffi.new("char[]", id_length) - - ret = lib.olm_outbound_group_session_id( - self._session, - id_buffer, - id_length - ) - self._check_error(ret) - - return bytes_to_native_str(ffi.unpack(id_buffer, id_length)) - - @property - def message_index(self): - # type: () -> int - """int: The current message index of the session. - - Each message is encrypted with an increasing index. This is the index - for the next message. - """ - return lib.olm_outbound_group_session_message_index(self._session) - - @property - def session_key(self): - # type: () -> str - """The base64-encoded current ratchet key for this session. - - Each message is encrypted with a different ratchet key. This function - returns the ratchet key that will be used for the next message. - """ - key_length = lib.olm_outbound_group_session_key_length(self._session) - key_buffer = ffi.new("char[]", key_length) - - ret = lib.olm_outbound_group_session_key( - self._session, - key_buffer, - key_length - ) - self._check_error(ret) - - return bytes_to_native_str(ffi.unpack(key_buffer, key_length)) diff --git a/python/olm/pk.py b/python/olm/pk.py deleted file mode 100644 index 4352359..0000000 --- a/python/olm/pk.py +++ /dev/null @@ -1,461 +0,0 @@ -# -*- coding: utf-8 -*- -# libolm python bindings -# Copyright © 2018 Damir Jelić <poljar@termina.org.uk> -# -# 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. -"""libolm PK module. - -This module contains bindings to the PK part of the Olm library. -It contains two classes PkDecryption and PkEncryption that are used to -establish an encrypted communication channel using public key encryption, -as well as a class PkSigning that is used to sign a message. - -Examples: - >>> decryption = PkDecryption() - >>> encryption = PkEncryption(decryption.public_key) - >>> plaintext = "It's a secret to everybody." - >>> message = encryption.encrypt(plaintext) - >>> decrypted_plaintext = decryption.decrypt(message) - >>> seed = PkSigning.generate_seed() - >>> signing = PkSigning(seed) - >>> signature = signing.sign(plaintext) - >>> ed25519_verify(signing.public_key, plaintext, signature) - -""" - -from builtins import super -from typing import AnyStr, Type - -from future.utils import bytes_to_native_str - -from _libolm import ffi, lib # type: ignore - -from ._compat import URANDOM, to_bytearray, to_unicode_str -from ._finalize import track_for_finalization - - -class PkEncryptionError(Exception): - """libolm Pk encryption exception.""" - - -class PkDecryptionError(Exception): - """libolm Pk decryption exception.""" - - -class PkSigningError(Exception): - """libolm Pk signing exception.""" - - -def _clear_pk_encryption(pk_struct): - lib.olm_clear_pk_encryption(pk_struct) - - -class PkMessage(object): - """A PK encrypted message.""" - - def __init__(self, ephemeral_key, mac, ciphertext): - # type: (str, str, str) -> None - """Create a new PK encrypted message. - - Args: - ephemeral_key(str): the public part of the ephemeral key - used (together with the recipient's key) to generate a symmetric - encryption key. - mac(str): Message Authentication Code of the encrypted message - ciphertext(str): The cipher text of the encrypted message - """ - self.ephemeral_key = ephemeral_key - self.mac = mac - self.ciphertext = ciphertext - - -class PkEncryption(object): - """PkEncryption class. - - Represents the decryption part of a PK encrypted channel. - """ - - def __init__(self, recipient_key): - # type: (AnyStr) -> None - """Create a new PK encryption object. - - Args: - recipient_key(str): a public key that will be used for encryption - """ - if not recipient_key: - raise ValueError("Recipient key can't be empty") - - self._buf = ffi.new("char[]", lib.olm_pk_encryption_size()) - self._pk_encryption = lib.olm_pk_encryption(self._buf) - track_for_finalization(self, self._pk_encryption, _clear_pk_encryption) - - byte_key = to_bytearray(recipient_key) - lib.olm_pk_encryption_set_recipient_key( - self._pk_encryption, - ffi.from_buffer(byte_key), - len(byte_key) - ) - - # clear out copies of the key - if byte_key is not recipient_key: # pragma: no cover - for i in range(0, len(byte_key)): - byte_key[i] = 0 - - def _check_error(self, ret): # pragma: no cover - # type: (int) -> None - if ret != lib.olm_error(): - return - - last_error = bytes_to_native_str( - ffi.string(lib.olm_pk_encryption_last_error(self._pk_encryption))) - - raise PkEncryptionError(last_error) - - def encrypt(self, plaintext): - # type: (AnyStr) -> PkMessage - """Encrypt a message. - - Returns the encrypted PkMessage. - - Args: - plaintext(str): A string that will be encrypted using the - PkEncryption object. - """ - byte_plaintext = to_bytearray(plaintext) - - r_length = lib.olm_pk_encrypt_random_length(self._pk_encryption) - random = URANDOM(r_length) - random_buffer = ffi.new("char[]", random) - - ciphertext_length = lib.olm_pk_ciphertext_length( - self._pk_encryption, len(byte_plaintext) - ) - ciphertext = ffi.new("char[]", ciphertext_length) - - mac_length = lib.olm_pk_mac_length(self._pk_encryption) - mac = ffi.new("char[]", mac_length) - - ephemeral_key_size = lib.olm_pk_key_length() - ephemeral_key = ffi.new("char[]", ephemeral_key_size) - - ret = lib.olm_pk_encrypt( - self._pk_encryption, - ffi.from_buffer(byte_plaintext), len(byte_plaintext), - ciphertext, ciphertext_length, - mac, mac_length, - ephemeral_key, ephemeral_key_size, - random_buffer, r_length - ) - - try: - self._check_error(ret) - finally: # pragma: no cover - # clear out copies of plaintext - if byte_plaintext is not plaintext: - for i in range(0, len(byte_plaintext)): - byte_plaintext[i] = 0 - - message = PkMessage( - bytes_to_native_str( - ffi.unpack(ephemeral_key, ephemeral_key_size)), - bytes_to_native_str( - ffi.unpack(mac, mac_length)), - bytes_to_native_str( - ffi.unpack(ciphertext, ciphertext_length)) - ) - return message - - -def _clear_pk_decryption(pk_struct): - lib.olm_clear_pk_decryption(pk_struct) - - -class PkDecryption(object): - """PkDecryption class. - - Represents the decryption part of a PK encrypted channel. - - Attributes: - public_key (str): The public key of the PkDecryption object, can be - shared and used to create a PkEncryption object. - - """ - - def __new__(cls): - # type: (Type[PkDecryption]) -> PkDecryption - obj = super().__new__(cls) - obj._buf = ffi.new("char[]", lib.olm_pk_decryption_size()) - obj._pk_decryption = lib.olm_pk_decryption(obj._buf) - obj.public_key = None - track_for_finalization(obj, obj._pk_decryption, _clear_pk_decryption) - return obj - - def __init__(self): - if False: # pragma: no cover - self._pk_decryption = self._pk_decryption # type: ffi.cdata - - random_length = lib.olm_pk_private_key_length() - random = URANDOM(random_length) - random_buffer = ffi.new("char[]", random) - - key_length = lib.olm_pk_key_length() - key_buffer = ffi.new("char[]", key_length) - - ret = lib.olm_pk_key_from_private( - self._pk_decryption, - key_buffer, key_length, - random_buffer, random_length - ) - self._check_error(ret) - self.public_key = bytes_to_native_str(ffi.unpack( - key_buffer, - key_length - )) - - def _check_error(self, ret): - # type: (int) -> None - if ret != lib.olm_error(): - return - - last_error = bytes_to_native_str( - ffi.string(lib.olm_pk_decryption_last_error(self._pk_decryption))) - - raise PkDecryptionError(last_error) - - def pickle(self, passphrase=""): - # type: (str) -> bytes - """Store a PkDecryption object. - - Stores a PkDecryption object as a base64 string. Encrypts the object - using the supplied passphrase. Returns a byte object containing the - base64 encoded string of the pickled session. - - Args: - passphrase(str, optional): The passphrase to be used to encrypt - the object. - """ - byte_key = to_bytearray(passphrase) - - pickle_length = lib.olm_pickle_pk_decryption_length( - self._pk_decryption - ) - pickle_buffer = ffi.new("char[]", pickle_length) - - ret = lib.olm_pickle_pk_decryption( - self._pk_decryption, - ffi.from_buffer(byte_key), len(byte_key), - pickle_buffer, pickle_length - ) - try: - self._check_error(ret) - finally: - # zero out copies of the passphrase - for i in range(0, len(byte_key)): - byte_key[i] = 0 - - return ffi.unpack(pickle_buffer, pickle_length) - - @classmethod - def from_pickle(cls, pickle, passphrase=""): - # types: (bytes, str) -> PkDecryption - """Restore a previously stored PkDecryption object. - - Creates a PkDecryption object from a pickled base64 string. Decrypts - the pickled object using the supplied passphrase. - Raises PkDecryptionError on failure. If the passphrase - doesn't match the one used to encrypt the session then the error - message for the exception will be "BAD_ACCOUNT_KEY". If the base64 - couldn't be decoded then the error message will be "INVALID_BASE64". - - Args: - pickle(bytes): Base64 encoded byte string containing the pickled - PkDecryption object - passphrase(str, optional): The passphrase used to encrypt the - object - """ - if not pickle: - raise ValueError("Pickle can't be empty") - - byte_key = to_bytearray(passphrase) - pickle_buffer = ffi.new("char[]", pickle) - - pubkey_length = lib.olm_pk_key_length() - pubkey_buffer = ffi.new("char[]", pubkey_length) - - obj = cls.__new__(cls) - - ret = lib.olm_unpickle_pk_decryption( - obj._pk_decryption, - ffi.from_buffer(byte_key), len(byte_key), - pickle_buffer, len(pickle), - pubkey_buffer, pubkey_length) - - try: - obj._check_error(ret) - finally: - for i in range(0, len(byte_key)): - byte_key[i] = 0 - - obj.public_key = bytes_to_native_str(ffi.unpack( - pubkey_buffer, - pubkey_length - )) - - return obj - - def decrypt(self, message, unicode_errors="replace"): - # type (PkMessage, str) -> str - """Decrypt a previously encrypted Pk message. - - Returns the decrypted plaintext. - Raises PkDecryptionError on failure. - - Args: - message(PkMessage): the pk message to decrypt. - unicode_errors(str, optional): The error handling scheme to use for - unicode decoding errors. The default is "replace" meaning that - the character that was unable to decode will be replaced with - the unicode replacement character (U+FFFD). Other possible - values are "strict", "ignore" and "xmlcharrefreplace" as well - as any other name registered with codecs.register_error that - can handle UnicodeEncodeErrors. - """ - ephemeral_key = to_bytearray(message.ephemeral_key) - ephemeral_key_size = len(ephemeral_key) - - mac = to_bytearray(message.mac) - mac_length = len(mac) - - ciphertext = to_bytearray(message.ciphertext) - ciphertext_length = len(ciphertext) - - max_plaintext_length = lib.olm_pk_max_plaintext_length( - self._pk_decryption, - ciphertext_length - ) - plaintext_buffer = ffi.new("char[]", max_plaintext_length) - - ret = lib.olm_pk_decrypt( - self._pk_decryption, - ffi.from_buffer(ephemeral_key), ephemeral_key_size, - ffi.from_buffer(mac), mac_length, - ffi.from_buffer(ciphertext), ciphertext_length, - plaintext_buffer, max_plaintext_length) - self._check_error(ret) - - plaintext = (ffi.unpack( - plaintext_buffer, - ret - )) - - # clear out copies of the plaintext - lib.memset(plaintext_buffer, 0, max_plaintext_length) - - return to_unicode_str(plaintext, errors=unicode_errors) - - -def _clear_pk_signing(pk_struct): - lib.olm_clear_pk_signing(pk_struct) - - -class PkSigning(object): - """PkSigning class. - - Signs messages using public key cryptography. - - Attributes: - public_key (str): The public key of the PkSigning object, can be - shared and used to verify using Utility.ed25519_verify. - - """ - - def __init__(self, seed): - # type: (bytes) -> None - """Create a new signing object. - - Args: - seed(bytes): the seed to use as the private key for signing. The - seed must have the same length as the seeds generated by - PkSigning.generate_seed(). - """ - if not seed: - raise ValueError("seed can't be empty") - - self._buf = ffi.new("char[]", lib.olm_pk_signing_size()) - self._pk_signing = lib.olm_pk_signing(self._buf) - track_for_finalization(self, self._pk_signing, _clear_pk_signing) - - seed_buffer = ffi.new("char[]", seed) - - pubkey_length = lib.olm_pk_signing_public_key_length() - pubkey_buffer = ffi.new("char[]", pubkey_length) - - ret = lib.olm_pk_signing_key_from_seed( - self._pk_signing, - pubkey_buffer, pubkey_length, - seed_buffer, len(seed) - ) - - # zero out copies of the seed - lib.memset(seed_buffer, 0, len(seed)) - - self._check_error(ret) - - self.public_key = bytes_to_native_str( - ffi.unpack(pubkey_buffer, pubkey_length) - ) - - def _check_error(self, ret): - # type: (int) -> None - if ret != lib.olm_error(): - return - - last_error = bytes_to_native_str( - ffi.string(lib.olm_pk_signing_last_error(self._pk_signing))) - - raise PkSigningError(last_error) - - @classmethod - def generate_seed(cls): - # type: () -> bytes - """Generate a random seed. - """ - random_length = lib.olm_pk_signing_seed_length() - random = URANDOM(random_length) - - return random - - def sign(self, message): - # type: (AnyStr) -> str - """Sign a message - - Returns the signature. - Raises PkSigningError on failure. - - Args: - message(str): the message to sign. - """ - bytes_message = to_bytearray(message) - - signature_length = lib.olm_pk_signature_length() - signature_buffer = ffi.new("char[]", signature_length) - - ret = lib.olm_pk_sign( - self._pk_signing, - ffi.from_buffer(bytes_message), len(bytes_message), - signature_buffer, signature_length) - self._check_error(ret) - - return bytes_to_native_str( - ffi.unpack(signature_buffer, signature_length) - ) diff --git a/python/olm/sas.py b/python/olm/sas.py deleted file mode 100644 index cf2a443..0000000 --- a/python/olm/sas.py +++ /dev/null @@ -1,245 +0,0 @@ -# -*- coding: utf-8 -*- -# libolm python bindings -# Copyright © 2019 Damir Jelić <poljar@termina.org.uk> -# -# 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. - -"""libolm SAS module. - -This module contains functions to perform key verification using the Short -Authentication String (SAS) method. - -Examples: - >>> sas = Sas() - >>> bob_key = "3p7bfXt9wbTTW2HC7OQ1Nz+DQ8hbeGdNrfx+FG+IK08" - >>> message = "Hello world!" - >>> extra_info = "MAC" - >>> sas_alice.set_their_pubkey(bob_key) - >>> sas_alice.calculate_mac(message, extra_info) - >>> sas_alice.generate_bytes(extra_info, 5) - -""" - -from builtins import bytes -from functools import wraps -from typing import Optional - -from future.utils import bytes_to_native_str - -from _libolm import ffi, lib - -from ._compat import URANDOM, to_bytearray, to_bytes -from ._finalize import track_for_finalization - - -def _clear_sas(sas): - # type: (ffi.cdata) -> None - lib.olm_clear_sas(sas) - - -class OlmSasError(Exception): - """libolm Sas error exception.""" - - -class Sas(object): - """libolm Short Authenticaton String (SAS) class.""" - - def __init__(self, other_users_pubkey=None): - # type: (Optional[str]) -> None - """Create a new SAS object. - - Args: - other_users_pubkey(str, optional): The other users public key, this - key is necesary to generate bytes for the authentication string - as well as to calculate the MAC. - - Raises OlmSasError on failure. - - """ - self._buf = ffi.new("char[]", lib.olm_sas_size()) - self._sas = lib.olm_sas(self._buf) - track_for_finalization(self, self._sas, _clear_sas) - - random_length = lib.olm_create_sas_random_length(self._sas) - random = URANDOM(random_length) - - self._create_sas(random, random_length) - - if other_users_pubkey: - self.set_their_pubkey(other_users_pubkey) - - def _create_sas(self, buffer, buffer_length): - self._check_error( - lib.olm_create_sas( - self._sas, - ffi.from_buffer(buffer), - buffer_length - ) - ) - - def _check_error(self, ret): - # type: (int) -> None - if ret != lib.olm_error(): - return - - last_error = bytes_to_native_str( - ffi.string((lib.olm_sas_last_error(self._sas)))) - - raise OlmSasError(last_error) - - @property - def pubkey(self): - # type: () -> str - """Get the public key for the SAS object. - - This returns the public key of the SAS object that can then be shared - with another user to perform the authentication process. - - Raises OlmSasError on failure. - - """ - pubkey_length = lib.olm_sas_pubkey_length(self._sas) - pubkey_buffer = ffi.new("char[]", pubkey_length) - - self._check_error( - lib.olm_sas_get_pubkey(self._sas, pubkey_buffer, pubkey_length) - ) - - return bytes_to_native_str(ffi.unpack(pubkey_buffer, pubkey_length)) - - @property - def other_key_set(self): - # type: () -> bool - """Check if the other user's pubkey has been set. - """ - return lib.olm_sas_is_their_key_set(self._sas) == 1 - - def set_their_pubkey(self, key): - # type: (str) -> None - """Set the public key of the other user. - - This sets the public key of the other user, it needs to be set before - bytes can be generated for the authentication string and a MAC can be - calculated. - - Args: - key (str): The other users public key. - - Raises OlmSasError on failure. - - """ - byte_key = to_bytearray(key) - - self._check_error( - lib.olm_sas_set_their_key( - self._sas, - ffi.from_buffer(byte_key), - len(byte_key) - ) - ) - - def generate_bytes(self, extra_info, length): - # type: (str, int) -> bytes - """Generate bytes to use for the short authentication string. - - Args: - extra_info (str): Extra information to mix in when generating the - bytes. - length (int): The number of bytes to generate. - - Raises OlmSasError if the other users persons public key isn't set or - an internal Olm error happens. - - """ - if length < 1: - raise ValueError("The length needs to be a positive integer value") - - byte_info = to_bytearray(extra_info) - out_buffer = ffi.new("char[]", length) - - self._check_error( - lib.olm_sas_generate_bytes( - self._sas, - ffi.from_buffer(byte_info), - len(byte_info), - out_buffer, - length - ) - ) - - return ffi.unpack(out_buffer, length) - - def calculate_mac(self, message, extra_info): - # type: (str, str) -> str - """Generate a message authentication code based on the shared secret. - - Args: - message (str): The message to produce the authentication code for. - extra_info (str): Extra information to mix in when generating the - MAC - - Raises OlmSasError on failure. - - """ - byte_message = to_bytes(message) - byte_info = to_bytes(extra_info) - - mac_length = lib.olm_sas_mac_length(self._sas) - mac_buffer = ffi.new("char[]", mac_length) - - self._check_error( - lib.olm_sas_calculate_mac( - self._sas, - ffi.from_buffer(byte_message), - len(byte_message), - ffi.from_buffer(byte_info), - len(byte_info), - mac_buffer, - mac_length - ) - ) - return bytes_to_native_str(ffi.unpack(mac_buffer, mac_length)) - - def calculate_mac_long_kdf(self, message, extra_info): - # type: (str, str) -> str - """Generate a message authentication code based on the shared secret. - - This function should not be used unless compatibility with an older - non-tagged Olm version is required. - - Args: - message (str): The message to produce the authentication code for. - extra_info (str): Extra information to mix in when generating the - MAC - - Raises OlmSasError on failure. - - """ - byte_message = to_bytes(message) - byte_info = to_bytes(extra_info) - - mac_length = lib.olm_sas_mac_length(self._sas) - mac_buffer = ffi.new("char[]", mac_length) - - self._check_error( - lib.olm_sas_calculate_mac_long_kdf( - self._sas, - ffi.from_buffer(byte_message), - len(byte_message), - ffi.from_buffer(byte_info), - len(byte_info), - mac_buffer, - mac_length - ) - ) - return bytes_to_native_str(ffi.unpack(mac_buffer, mac_length)) diff --git a/python/olm/session.py b/python/olm/session.py deleted file mode 100644 index 636eb3d..0000000 --- a/python/olm/session.py +++ /dev/null @@ -1,495 +0,0 @@ -# -*- coding: utf-8 -*- -# libolm python bindings -# Copyright © 2015-2017 OpenMarket Ltd -# Copyright © 2018 Damir Jelić <poljar@termina.org.uk> -# -# 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. -"""libolm Session module. - -This module contains the Olm Session part of the Olm library. - -It is used to establish a peer-to-peer encrypted communication channel between -two Olm accounts. - -Examples: - >>> alice = Account() - >>> bob = Account() - >>> bob.generate_one_time_keys(1) - >>> id_key = bob.identity_keys['curve25519'] - >>> one_time = list(bob.one_time_keys["curve25519"].values())[0] - >>> session = OutboundSession(alice, id_key, one_time) - -""" - -# pylint: disable=redefined-builtin,unused-import -from builtins import bytes, super -from typing import AnyStr, Optional, Type - -from future.utils import bytes_to_native_str - -# pylint: disable=no-name-in-module -from _libolm import ffi, lib # type: ignore - -from ._compat import URANDOM, to_bytearray, to_bytes, to_unicode_str -from ._finalize import track_for_finalization - -# This is imported only for type checking purposes -if False: - from .account import Account # pragma: no cover - - -class OlmSessionError(Exception): - """libolm Session exception.""" - - -class _OlmMessage(object): - def __init__(self, ciphertext, message_type): - # type: (AnyStr, ffi.cdata) -> None - if not ciphertext: - raise ValueError("Ciphertext can't be empty") - - # I don't know why mypy wants a type annotation here nor why AnyStr - # doesn't work - self.ciphertext = ciphertext # type: ignore - self.message_type = message_type - - def __str__(self): - # type: () -> str - type_to_prefix = { - lib.OLM_MESSAGE_TYPE_PRE_KEY: "PRE_KEY", - lib.OLM_MESSAGE_TYPE_MESSAGE: "MESSAGE" - } - - prefix = type_to_prefix[self.message_type] - return "{} {}".format(prefix, self.ciphertext) - - -class OlmPreKeyMessage(_OlmMessage): - """Olm prekey message class - - Prekey messages are used to establish an Olm session. After the first - message exchange the session switches to normal messages - """ - - def __init__(self, ciphertext): - # type: (AnyStr) -> None - """Create a new Olm prekey message with the supplied ciphertext - - Args: - ciphertext(str): The ciphertext of the prekey message. - """ - _OlmMessage.__init__(self, ciphertext, lib.OLM_MESSAGE_TYPE_PRE_KEY) - - def __repr__(self): - # type: () -> str - return "OlmPreKeyMessage({})".format(self.ciphertext) - - -class OlmMessage(_OlmMessage): - """Olm message class""" - - def __init__(self, ciphertext): - # type: (AnyStr) -> None - """Create a new Olm message with the supplied ciphertext - - Args: - ciphertext(str): The ciphertext of the message. - """ - _OlmMessage.__init__(self, ciphertext, lib.OLM_MESSAGE_TYPE_MESSAGE) - - def __repr__(self): - # type: () -> str - return "OlmMessage({})".format(self.ciphertext) - - -def _clear_session(session): - # type: (ffi.cdata) -> None - lib.olm_clear_session(session) - - -class Session(object): - """libolm Session class. - This is an abstract class that can't be instantiated except when unpickling - a previously pickled InboundSession or OutboundSession object with - from_pickle. - """ - - def __new__(cls): - # type: (Type[Session]) -> Session - - obj = super().__new__(cls) - obj._buf = ffi.new("char[]", lib.olm_session_size()) - obj._session = lib.olm_session(obj._buf) - track_for_finalization(obj, obj._session, _clear_session) - return obj - - def __init__(self): - # type: () -> None - if type(self) is Session: - raise TypeError("Session class may not be instantiated.") - - if False: - self._session = self._session # type: ffi.cdata - - def _check_error(self, ret): - # type: (int) -> None - if ret != lib.olm_error(): - return - - last_error = bytes_to_native_str( - ffi.string(lib.olm_session_last_error(self._session))) - - raise OlmSessionError(last_error) - - def pickle(self, passphrase=""): - # type: (Optional[str]) -> bytes - """Store an Olm session. - - Stores a session as a base64 string. Encrypts the session using the - supplied passphrase. Returns a byte object containing the base64 - encoded string of the pickled session. Raises OlmSessionError on - failure. - - Args: - passphrase(str, optional): The passphrase to be used to encrypt - the session. - """ - byte_key = bytearray(passphrase, "utf-8") if passphrase else b"" - - pickle_length = lib.olm_pickle_session_length(self._session) - pickle_buffer = ffi.new("char[]", pickle_length) - - try: - self._check_error( - lib.olm_pickle_session(self._session, - ffi.from_buffer(byte_key), - len(byte_key), - pickle_buffer, pickle_length)) - finally: - # clear out copies of the passphrase - for i in range(0, len(byte_key)): - byte_key[i] = 0 - - return ffi.unpack(pickle_buffer, pickle_length) - - @classmethod - def from_pickle(cls, pickle, passphrase=""): - # type: (bytes, Optional[str]) -> Session - """Load a previously stored Olm session. - - Loads a session from a pickled base64 string and returns a Session - object. Decrypts the session using the supplied passphrase. Raises - OlmSessionError on failure. If the passphrase doesn't match the one - used to encrypt the session then the error message for the - exception will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded - then the error message will be "INVALID_BASE64". - - Args: - pickle(bytes): Base64 encoded byte string containing the pickled - session - passphrase(str, optional): The passphrase used to encrypt the - session. - """ - if not pickle: - raise ValueError("Pickle can't be empty") - - byte_key = bytearray(passphrase, "utf-8") if passphrase else b"" - # copy because unpickle will destroy the buffer - pickle_buffer = ffi.new("char[]", pickle) - - session = cls.__new__(cls) - - try: - ret = lib.olm_unpickle_session(session._session, - ffi.from_buffer(byte_key), - len(byte_key), - pickle_buffer, - len(pickle)) - session._check_error(ret) - finally: - # clear out copies of the passphrase - for i in range(0, len(byte_key)): - byte_key[i] = 0 - - return session - - def encrypt(self, plaintext): - # type: (AnyStr) -> _OlmMessage - """Encrypts a message using the session. Returns the ciphertext as a - base64 encoded string on success. Raises OlmSessionError on failure. - - Args: - plaintext(str): The plaintext message that will be encrypted. - """ - byte_plaintext = to_bytearray(plaintext) - - r_length = lib.olm_encrypt_random_length(self._session) - random = URANDOM(r_length) - - try: - message_type = lib.olm_encrypt_message_type(self._session) - - self._check_error(message_type) - - ciphertext_length = lib.olm_encrypt_message_length( - self._session, len(byte_plaintext) - ) - ciphertext_buffer = ffi.new("char[]", ciphertext_length) - - self._check_error(lib.olm_encrypt( - self._session, - ffi.from_buffer(byte_plaintext), len(byte_plaintext), - ffi.from_buffer(random), r_length, - ciphertext_buffer, ciphertext_length, - )) - finally: - # clear out copies of plaintext - if byte_plaintext is not plaintext: - for i in range(0, len(byte_plaintext)): - byte_plaintext[i] = 0 - - if message_type == lib.OLM_MESSAGE_TYPE_PRE_KEY: - return OlmPreKeyMessage( - bytes_to_native_str(ffi.unpack( - ciphertext_buffer, - ciphertext_length - ))) - elif message_type == lib.OLM_MESSAGE_TYPE_MESSAGE: - return OlmMessage( - bytes_to_native_str(ffi.unpack( - ciphertext_buffer, - ciphertext_length - ))) - else: # pragma: no cover - raise ValueError("Unknown message type") - - def decrypt(self, message, unicode_errors="replace"): - # type: (_OlmMessage, str) -> str - """Decrypts a message using the session. Returns the plaintext string - on success. Raises OlmSessionError on failure. If the base64 couldn't - be decoded then the error message will be "INVALID_BASE64". If the - message is for an unsupported version of the protocol the error message - will be "BAD_MESSAGE_VERSION". If the message couldn't be decoded then - the error message will be "BAD_MESSAGE_FORMAT". If the MAC on the - message was invalid then the error message will be "BAD_MESSAGE_MAC". - - Args: - message(OlmMessage): The Olm message that will be decrypted. It can - be either an OlmPreKeyMessage or an OlmMessage. - unicode_errors(str, optional): The error handling scheme to use for - unicode decoding errors. The default is "replace" meaning that - the character that was unable to decode will be replaced with - the unicode replacement character (U+FFFD). Other possible - values are "strict", "ignore" and "xmlcharrefreplace" as well - as any other name registered with codecs.register_error that - can handle UnicodeEncodeErrors. - """ - if not message.ciphertext: - raise ValueError("Ciphertext can't be empty") - - byte_ciphertext = to_bytes(message.ciphertext) - # make a copy the ciphertext buffer, because - # olm_decrypt_max_plaintext_length wants to destroy something - ciphertext_buffer = ffi.new("char[]", byte_ciphertext) - - max_plaintext_length = lib.olm_decrypt_max_plaintext_length( - self._session, message.message_type, ciphertext_buffer, - len(byte_ciphertext) - ) - self._check_error(max_plaintext_length) - plaintext_buffer = ffi.new("char[]", max_plaintext_length) - - # make a copy the ciphertext buffer, because - # olm_decrypt_max_plaintext_length wants to destroy something - ciphertext_buffer = ffi.new("char[]", byte_ciphertext) - plaintext_length = lib.olm_decrypt( - self._session, message.message_type, - ciphertext_buffer, len(byte_ciphertext), - plaintext_buffer, max_plaintext_length - ) - self._check_error(plaintext_length) - plaintext = to_unicode_str( - ffi.unpack(plaintext_buffer, plaintext_length), - errors=unicode_errors - ) - - # clear out copies of the plaintext - lib.memset(plaintext_buffer, 0, max_plaintext_length) - - return plaintext - - @property - def id(self): - # type: () -> str - """str: An identifier for this session. Will be the same for both - ends of the conversation. - """ - id_length = lib.olm_session_id_length(self._session) - id_buffer = ffi.new("char[]", id_length) - - self._check_error( - lib.olm_session_id(self._session, id_buffer, id_length) - ) - return bytes_to_native_str(ffi.unpack(id_buffer, id_length)) - - def matches(self, message, identity_key=None): - # type: (OlmPreKeyMessage, Optional[AnyStr]) -> bool - """Checks if the PRE_KEY message is for this in-bound session. - This can happen if multiple messages are sent to this session before - this session sends a message in reply. Returns True if the session - matches. Returns False if the session does not match. Raises - OlmSessionError on failure. If the base64 couldn't be decoded then the - error message will be "INVALID_BASE64". If the message was for an - unsupported protocol version then the error message will be - "BAD_MESSAGE_VERSION". If the message couldn't be decoded then then the - error message will be * "BAD_MESSAGE_FORMAT". - - Args: - message(OlmPreKeyMessage): The Olm prekey message that will checked - if it is intended for this session. - identity_key(str, optional): The identity key of the sender. To - check if the message was also sent using this identity key. - """ - if not isinstance(message, OlmPreKeyMessage): - raise TypeError("Matches can only be called with prekey messages.") - - if not message.ciphertext: - raise ValueError("Ciphertext can't be empty") - - ret = None - - byte_ciphertext = to_bytes(message.ciphertext) - # make a copy, because olm_matches_inbound_session(_from) will distroy - # it - message_buffer = ffi.new("char[]", byte_ciphertext) - - if identity_key: - byte_id_key = to_bytes(identity_key) - - ret = lib.olm_matches_inbound_session_from( - self._session, - ffi.from_buffer(byte_id_key), len(byte_id_key), - message_buffer, len(byte_ciphertext) - ) - - else: - ret = lib.olm_matches_inbound_session( - self._session, - message_buffer, len(byte_ciphertext)) - - self._check_error(ret) - - return bool(ret) - - -class InboundSession(Session): - """Inbound Olm session for p2p encrypted communication. - """ - - def __new__(cls, account, message, identity_key=None): - # type: (Account, OlmPreKeyMessage, Optional[AnyStr]) -> Session - return super().__new__(cls) - - def __init__(self, account, message, identity_key=None): - # type: (Account, OlmPreKeyMessage, Optional[AnyStr]) -> None - """Create a new inbound Olm session. - - Create a new in-bound session for sending/receiving messages from an - incoming prekey message. Raises OlmSessionError on failure. If the - base64 couldn't be decoded then error message will be "INVALID_BASE64". - If the message was for an unsupported protocol version then - the errror message will be "BAD_MESSAGE_VERSION". If the message - couldn't be decoded then then the error message will be - "BAD_MESSAGE_FORMAT". If the message refers to an unknown one-time - key then the error message will be "BAD_MESSAGE_KEY_ID". - - Args: - account(Account): The Olm Account that will be used to create this - session. - message(OlmPreKeyMessage): The Olm prekey message that will checked - that will be used to create this session. - identity_key(str, optional): The identity key of the sender. To - check if the message was also sent using this identity key. - """ - if not message.ciphertext: - raise ValueError("Ciphertext can't be empty") - - super().__init__() - byte_ciphertext = to_bytes(message.ciphertext) - message_buffer = ffi.new("char[]", byte_ciphertext) - - if identity_key: - byte_id_key = to_bytes(identity_key) - identity_key_buffer = ffi.new("char[]", byte_id_key) - self._check_error(lib.olm_create_inbound_session_from( - self._session, - account._account, - identity_key_buffer, len(byte_id_key), - message_buffer, len(byte_ciphertext) - )) - else: - self._check_error(lib.olm_create_inbound_session( - self._session, - account._account, - message_buffer, len(byte_ciphertext) - )) - - -class OutboundSession(Session): - """Outbound Olm session for p2p encrypted communication.""" - - def __new__(cls, account, identity_key, one_time_key): - # type: (Account, AnyStr, AnyStr) -> Session - return super().__new__(cls) - - def __init__(self, account, identity_key, one_time_key): - # type: (Account, AnyStr, AnyStr) -> None - """Create a new outbound Olm session. - - Creates a new outbound session for sending messages to a given - identity key and one-time key. - - Raises OlmSessionError on failure. If the keys couldn't be decoded as - base64 then the error message will be "INVALID_BASE64". - - Args: - account(Account): The Olm Account that will be used to create this - session. - identity_key(str): The identity key of the person with whom we want - to start the session. - one_time_key(str): A one-time key from the person with whom we want - to start the session. - """ - if not identity_key: - raise ValueError("Identity key can't be empty") - - if not one_time_key: - raise ValueError("One-time key can't be empty") - - super().__init__() - - byte_id_key = to_bytes(identity_key) - byte_one_time = to_bytes(one_time_key) - - session_random_length = lib.olm_create_outbound_session_random_length( - self._session) - - random = URANDOM(session_random_length) - - self._check_error(lib.olm_create_outbound_session( - self._session, - account._account, - ffi.from_buffer(byte_id_key), len(byte_id_key), - ffi.from_buffer(byte_one_time), len(byte_one_time), - ffi.from_buffer(random), session_random_length - )) diff --git a/python/olm/utility.py b/python/olm/utility.py deleted file mode 100644 index bddef38..0000000 --- a/python/olm/utility.py +++ /dev/null @@ -1,151 +0,0 @@ -# -*- coding: utf-8 -*- -# libolm python bindings -# Copyright © 2015-2017 OpenMarket Ltd -# Copyright © 2018 Damir Jelić <poljar@termina.org.uk> -# -# 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. -"""libolm Utility module. - -This module contains utilities for olm. -It only contains the ed25519_verify function for signature verification. - -Examples: - >>> alice = Account() - - >>> message = "Test" - >>> signature = alice.sign(message) - >>> signing_key = alice.identity_keys["ed25519"] - - >>> ed25519_verify(signing_key, message, signature) - -""" - -# pylint: disable=redefined-builtin,unused-import -from typing import AnyStr, Type - -from future.utils import bytes_to_native_str - -# pylint: disable=no-name-in-module -from _libolm import ffi, lib # type: ignore - -from ._compat import to_bytearray, to_bytes -from ._finalize import track_for_finalization - - -def _clear_utility(utility): # pragma: no cover - # type: (ffi.cdata) -> None - lib.olm_clear_utility(utility) - - -class OlmVerifyError(Exception): - """libolm signature verification exception.""" - - -class OlmHashError(Exception): - """libolm hash calculation exception.""" - - -class _Utility(object): - # pylint: disable=too-few-public-methods - """libolm Utility class.""" - - _buf = None - _utility = None - - @classmethod - def _allocate(cls): - # type: (Type[_Utility]) -> None - cls._buf = ffi.new("char[]", lib.olm_utility_size()) - cls._utility = lib.olm_utility(cls._buf) - track_for_finalization(cls, cls._utility, _clear_utility) - - @classmethod - def _check_error(cls, ret, error_class): - # type: (int, Type) -> None - if ret != lib.olm_error(): - return - - raise error_class("{}".format( - ffi.string(lib.olm_utility_last_error( - cls._utility)).decode("utf-8"))) - - @classmethod - def _ed25519_verify(cls, key, message, signature): - # type: (Type[_Utility], AnyStr, AnyStr, AnyStr) -> None - if not cls._utility: - cls._allocate() - - byte_key = to_bytes(key) - byte_message = to_bytearray(message) - byte_signature = to_bytearray(signature) - - try: - ret = lib.olm_ed25519_verify( - cls._utility, - byte_key, - len(byte_key), - ffi.from_buffer(byte_message), - len(byte_message), - ffi.from_buffer(byte_signature), - len(byte_signature) - ) - - cls._check_error(ret, OlmVerifyError) - - finally: - # clear out copies of the message, which may be a plaintext - if byte_message is not message: - for i in range(0, len(byte_message)): - byte_message[i] = 0 - - @classmethod - def _sha256(cls, input): - # type: (Type[_Utility], AnyStr) -> str - if not cls._utility: - cls._allocate() - - byte_input = to_bytes(input) - hash_length = lib.olm_sha256_length(cls._utility) - hash = ffi.new("char[]", hash_length) - - ret = lib.olm_sha256(cls._utility, byte_input, len(byte_input), - hash, hash_length) - - cls._check_error(ret, OlmHashError) - - return bytes_to_native_str(ffi.unpack(hash, hash_length)) - - -def ed25519_verify(key, message, signature): - # type: (AnyStr, AnyStr, AnyStr) -> None - """Verify an ed25519 signature. - - Raises an OlmVerifyError if verification fails. - - Args: - key(str): The ed25519 public key used for signing. - message(str): The signed message. - signature(bytes): The message signature. - """ - return _Utility._ed25519_verify(key, message, signature) - - -def sha256(input_string): - # type: (AnyStr) -> str - """Calculate the SHA-256 hash of the input and encodes it as base64. - - Args: - input_string(str): The input for which the hash will be calculated. - - """ - return _Utility._sha256(input_string) diff --git a/python/olm_build.py b/python/olm_build.py deleted file mode 100644 index 0606337..0000000 --- a/python/olm_build.py +++ /dev/null @@ -1,62 +0,0 @@ -# -*- coding: utf-8 -*- - -# libolm python bindings -# Copyright © 2018 Damir Jelić <poljar@termina.org.uk> -# -# Permission to use, copy, modify, and/or distribute this software for -# any purpose with or without fee is hereby granted, provided that the -# above copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -from __future__ import unicode_literals - -import os -import subprocess - -from cffi import FFI - -ffibuilder = FFI() -PATH = os.path.dirname(__file__) - -DEVELOP = os.environ.get("DEVELOP") - -compile_args = ["-I../include"] -link_args = ["-L../build"] - -if DEVELOP and DEVELOP.lower() in ["yes", "true", "1"]: - link_args.append('-Wl,-rpath=../build') - -headers_build = subprocess.Popen("make headers", shell=True) -headers_build.wait() - -ffibuilder.set_source( - "_libolm", - r""" - #include <olm/olm.h> - #include <olm/inbound_group_session.h> - #include <olm/outbound_group_session.h> - #include <olm/pk.h> - #include <olm/sas.h> - """, - libraries=["olm"], - extra_compile_args=compile_args, - extra_link_args=link_args) - -with open(os.path.join(PATH, "include/olm/olm.h")) as f: - ffibuilder.cdef(f.read(), override=True) - -with open(os.path.join(PATH, "include/olm/pk.h")) as f: - ffibuilder.cdef(f.read(), override=True) - -with open(os.path.join(PATH, "include/olm/sas.h")) as f: - ffibuilder.cdef(f.read(), override=True) - -if __name__ == "__main__": - ffibuilder.compile(verbose=True) diff --git a/python/requirements.txt b/python/requirements.txt deleted file mode 100644 index c627b85..0000000 --- a/python/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -future -cffi -typing diff --git a/python/setup.cfg b/python/setup.cfg deleted file mode 100644 index d10b7e4..0000000 --- a/python/setup.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[tool:pytest] -testpaths = tests -flake8-ignore = - olm/*.py F401 - tests/*.py W503 - -[coverage:run] -omit=olm/__version__.py diff --git a/python/setup.py b/python/setup.py deleted file mode 100644 index 5742fd9..0000000 --- a/python/setup.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- - -import os -from codecs import open - -from setuptools import setup - -here = os.path.abspath(os.path.dirname(__file__)) - -about = {} -with open(os.path.join(here, "olm", "__version__.py"), "r", "utf-8") as f: - exec(f.read(), about) - -setup( - name=about["__title__"], - version=about["__version__"], - description=about["__description__"], - author=about["__author__"], - author_email=about["__author_email__"], - url=about["__url__"], - license=about["__license__"], - packages=["olm"], - setup_requires=["cffi>=1.0.0"], - cffi_modules=["olm_build.py:ffibuilder"], - install_requires=[ - "cffi>=1.0.0", - "future", - "typing;python_version<'3.5'" - ], - zip_safe=False -) diff --git a/python/test-requirements.txt b/python/test-requirements.txt deleted file mode 100644 index b18f27f..0000000 --- a/python/test-requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -pytest -pytest-flake8 -pytest-isort -pytest-cov -pytest-benchmark -aspectlib diff --git a/python/tests/account_test.py b/python/tests/account_test.py deleted file mode 100644 index f3b71eb..0000000 --- a/python/tests/account_test.py +++ /dev/null @@ -1,114 +0,0 @@ -from builtins import int - -import pytest - -from olm import Account, OlmAccountError, OlmVerifyError, ed25519_verify -from olm._compat import to_bytes - - -class TestClass(object): - def test_to_bytes(self): - assert isinstance(to_bytes("a"), bytes) - assert isinstance(to_bytes(u"a"), bytes) - assert isinstance(to_bytes(b"a"), bytes) - assert isinstance(to_bytes(r"a"), bytes) - with pytest.raises(TypeError): - to_bytes(0) - - def test_account_creation(self): - alice = Account() - assert alice.identity_keys - assert len(alice.identity_keys) == 2 - - def test_account_pickle(self): - alice = Account() - pickle = alice.pickle() - assert (alice.identity_keys == Account.from_pickle(pickle) - .identity_keys) - - def test_invalid_unpickle(self): - with pytest.raises(ValueError): - Account.from_pickle(b"") - - def test_passphrase_pickle(self): - alice = Account() - passphrase = "It's a secret to everybody" - pickle = alice.pickle(passphrase) - assert (alice.identity_keys == Account.from_pickle( - pickle, passphrase).identity_keys) - - def test_wrong_passphrase_pickle(self): - alice = Account() - passphrase = "It's a secret to everybody" - pickle = alice.pickle(passphrase) - - with pytest.raises(OlmAccountError): - Account.from_pickle(pickle, "") - - def test_one_time_keys(self): - alice = Account() - alice.generate_one_time_keys(10) - one_time_keys = alice.one_time_keys - assert one_time_keys - assert len(one_time_keys["curve25519"]) == 10 - - def test_max_one_time_keys(self): - alice = Account() - assert isinstance(alice.max_one_time_keys, int) - - def test_publish_one_time_keys(self): - alice = Account() - alice.generate_one_time_keys(10) - one_time_keys = alice.one_time_keys - - assert one_time_keys - assert len(one_time_keys["curve25519"]) == 10 - - alice.mark_keys_as_published() - assert not alice.one_time_keys["curve25519"] - - def test_clear(self): - alice = Account() - del alice - - def test_valid_signature(self): - message = "It's a secret to everybody" - alice = Account() - - signature = alice.sign(message) - signing_key = alice.identity_keys["ed25519"] - - assert signature - assert signing_key - - ed25519_verify(signing_key, message, signature) - - def test_invalid_signature(self): - message = "It's a secret to everybody" - alice = Account() - bob = Account() - - signature = alice.sign(message) - signing_key = bob.identity_keys["ed25519"] - - assert signature - assert signing_key - - with pytest.raises(OlmVerifyError): - ed25519_verify(signing_key, message, signature) - - def test_signature_verification_twice(self): - message = "It's a secret to everybody" - alice = Account() - - signature = alice.sign(message) - signing_key = alice.identity_keys["ed25519"] - - assert signature - assert signing_key - - ed25519_verify(signing_key, message, signature) - assert signature == alice.sign(message) - - ed25519_verify(signing_key, message, signature) - assert signature == alice.sign(message) diff --git a/python/tests/group_session_test.py b/python/tests/group_session_test.py deleted file mode 100644 index 4632a60..0000000 --- a/python/tests/group_session_test.py +++ /dev/null @@ -1,128 +0,0 @@ -# -*- coding: utf-8 -*- -import pytest - -from olm import InboundGroupSession, OlmGroupSessionError, OutboundGroupSession - - -class TestClass(object): - def test_session_create(self): - OutboundGroupSession() - - def test_session_id(self): - session = OutboundGroupSession() - assert isinstance(session.id, str) - - def test_session_index(self): - session = OutboundGroupSession() - assert isinstance(session.message_index, int) - assert session.message_index == 0 - - def test_outbound_pickle(self): - session = OutboundGroupSession() - pickle = session.pickle() - - assert (session.id == OutboundGroupSession.from_pickle( - pickle).id) - - def test_invalid_unpickle(self): - with pytest.raises(ValueError): - OutboundGroupSession.from_pickle(b"") - - with pytest.raises(ValueError): - InboundGroupSession.from_pickle(b"") - - def test_inbound_create(self): - outbound = OutboundGroupSession() - InboundGroupSession(outbound.session_key) - - def test_invalid_decrypt(self): - outbound = OutboundGroupSession() - inbound = InboundGroupSession(outbound.session_key) - - with pytest.raises(ValueError): - inbound.decrypt("") - - def test_inbound_pickle(self): - outbound = OutboundGroupSession() - inbound = InboundGroupSession(outbound.session_key) - pickle = inbound.pickle() - InboundGroupSession.from_pickle(pickle) - - def test_inbound_export(self): - outbound = OutboundGroupSession() - inbound = InboundGroupSession(outbound.session_key) - imported = InboundGroupSession.import_session( - inbound.export_session(inbound.first_known_index) - ) - assert "Test", 0 == imported.decrypt(outbound.encrypt("Test")) - - def test_first_index(self): - outbound = OutboundGroupSession() - inbound = InboundGroupSession(outbound.session_key) - index = inbound.first_known_index - assert isinstance(index, int) - - def test_encrypt(self, benchmark): - benchmark.weave(OutboundGroupSession.encrypt, lazy=True) - outbound = OutboundGroupSession() - inbound = InboundGroupSession(outbound.session_key) - assert "Test", 0 == inbound.decrypt(outbound.encrypt("Test")) - - def test_decrypt(self, benchmark): - benchmark.weave(InboundGroupSession.decrypt, lazy=True) - outbound = OutboundGroupSession() - inbound = InboundGroupSession(outbound.session_key) - assert "Test", 0 == inbound.decrypt(outbound.encrypt("Test")) - - def test_decrypt_twice(self): - outbound = OutboundGroupSession() - inbound = InboundGroupSession(outbound.session_key) - outbound.encrypt("Test 1") - message, index = inbound.decrypt(outbound.encrypt("Test 2")) - assert isinstance(index, int) - assert ("Test 2", 1) == (message, index) - - def test_decrypt_failure(self): - outbound = OutboundGroupSession() - inbound = InboundGroupSession(outbound.session_key) - eve_outbound = OutboundGroupSession() - with pytest.raises(OlmGroupSessionError): - inbound.decrypt(eve_outbound.encrypt("Test")) - - def test_id(self): - outbound = OutboundGroupSession() - inbound = InboundGroupSession(outbound.session_key) - assert outbound.id == inbound.id - - def test_inbound_fail(self): - with pytest.raises(TypeError): - InboundGroupSession() - - def test_oubtound_pickle_fail(self): - outbound = OutboundGroupSession() - pickle = outbound.pickle("Test") - - with pytest.raises(OlmGroupSessionError): - OutboundGroupSession.from_pickle(pickle) - - def test_outbound_clear(self): - session = OutboundGroupSession() - del session - - def test_inbound_clear(self): - outbound = OutboundGroupSession() - inbound = InboundGroupSession(outbound.session_key) - del inbound - - def test_invalid_unicode_decrypt(self): - outbound = OutboundGroupSession() - inbound = InboundGroupSession(outbound.session_key) - - text = outbound.encrypt(b"\xed") - plaintext, _ = inbound.decrypt(text) - - print(plaintext) - assert plaintext == u"�" - - plaintext, _ = inbound.decrypt(text, "ignore") - assert plaintext == "" diff --git a/python/tests/pk_test.py b/python/tests/pk_test.py deleted file mode 100644 index ef87465..0000000 --- a/python/tests/pk_test.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- coding: utf-8 -*- -import pytest - -from olm import (PkDecryption, PkDecryptionError, PkEncryption, PkSigning, - ed25519_verify) - - -class TestClass(object): - def test_invalid_encryption(self): - with pytest.raises(ValueError): - PkEncryption("") - - def test_decrytion(self): - decryption = PkDecryption() - encryption = PkEncryption(decryption.public_key) - plaintext = "It's a secret to everybody." - message = encryption.encrypt(plaintext) - decrypted_plaintext = decryption.decrypt(message) - isinstance(decrypted_plaintext, str) - assert plaintext == decrypted_plaintext - - def test_invalid_decrytion(self): - decryption = PkDecryption() - encryption = PkEncryption(decryption.public_key) - plaintext = "It's a secret to everybody." - message = encryption.encrypt(plaintext) - message.ephemeral_key = "?" - with pytest.raises(PkDecryptionError): - decryption.decrypt(message) - - def test_pickling(self): - decryption = PkDecryption() - encryption = PkEncryption(decryption.public_key) - plaintext = "It's a secret to everybody." - message = encryption.encrypt(plaintext) - - pickle = decryption.pickle() - unpickled = PkDecryption.from_pickle(pickle) - decrypted_plaintext = unpickled.decrypt(message) - assert plaintext == decrypted_plaintext - - def test_invalid_unpickling(self): - with pytest.raises(ValueError): - PkDecryption.from_pickle("") - - def test_invalid_pass_pickling(self): - decryption = PkDecryption() - pickle = decryption.pickle("Secret") - - with pytest.raises(PkDecryptionError): - PkDecryption.from_pickle(pickle, "Not secret") - - def test_signing(self): - seed = PkSigning.generate_seed() - signing = PkSigning(seed) - message = "This statement is true" - signature = signing.sign(message) - ed25519_verify(signing.public_key, message, signature) - - def test_invalid_unicode_decrypt(self): - decryption = PkDecryption() - encryption = PkEncryption(decryption.public_key) - message = encryption.encrypt(b"\xed") - plaintext = decryption.decrypt(message) - assert plaintext == u"�" diff --git a/python/tests/sas_test.py b/python/tests/sas_test.py deleted file mode 100644 index 9001e67..0000000 --- a/python/tests/sas_test.py +++ /dev/null @@ -1,99 +0,0 @@ -from builtins import bytes - -import pytest - -from olm import OlmSasError, Sas - -MESSAGE = "Test message" -EXTRA_INFO = "extra_info" - - -class TestClass(object): - def test_sas_creation(self): - sas = Sas() - assert sas.pubkey - - def test_other_key_setting(self): - sas_alice = Sas() - sas_bob = Sas() - - assert not sas_alice.other_key_set - sas_alice.set_their_pubkey(sas_bob.pubkey) - assert sas_alice.other_key_set - - def test_bytes_generating(self): - sas_alice = Sas() - sas_bob = Sas(sas_alice.pubkey) - - assert sas_bob.other_key_set - - with pytest.raises(OlmSasError): - sas_alice.generate_bytes(EXTRA_INFO, 5) - - sas_alice.set_their_pubkey(sas_bob.pubkey) - - with pytest.raises(ValueError): - sas_alice.generate_bytes(EXTRA_INFO, 0) - - alice_bytes = sas_alice.generate_bytes(EXTRA_INFO, 5) - bob_bytes = sas_bob.generate_bytes(EXTRA_INFO, 5) - - assert alice_bytes == bob_bytes - - def test_mac_generating(self): - sas_alice = Sas() - sas_bob = Sas() - - with pytest.raises(OlmSasError): - sas_alice.calculate_mac(MESSAGE, EXTRA_INFO) - - sas_alice.set_their_pubkey(sas_bob.pubkey) - sas_bob.set_their_pubkey(sas_alice.pubkey) - - alice_mac = sas_alice.calculate_mac(MESSAGE, EXTRA_INFO) - bob_mac = sas_bob.calculate_mac(MESSAGE, EXTRA_INFO) - - assert alice_mac == bob_mac - - def test_cross_language_mac(self): - """Test MAC generating with a predefined key pair. - - This test imports a private and public key from the C test and checks - if we are getting the same MAC that the C code calculated. - """ - alice_private = [ - 0x77, 0x07, 0x6D, 0x0A, 0x73, 0x18, 0xA5, 0x7D, - 0x3C, 0x16, 0xC1, 0x72, 0x51, 0xB2, 0x66, 0x45, - 0xDF, 0x4C, 0x2F, 0x87, 0xEB, 0xC0, 0x99, 0x2A, - 0xB1, 0x77, 0xFB, 0xA5, 0x1D, 0xB9, 0x2C, 0x2A - ] - - bob_key = "3p7bfXt9wbTTW2HC7OQ1Nz+DQ8hbeGdNrfx+FG+IK08" - message = "Hello world!" - extra_info = "MAC" - expected_mac = "2nSMTXM+TStTU3RUVTNSVVZUTlNWVlpVVGxOV1ZscFY" - - sas_alice = Sas() - sas_alice._create_sas(bytes(alice_private), 32) - sas_alice.set_their_pubkey(bob_key) - - alice_mac = sas_alice.calculate_mac(message, extra_info) - - assert alice_mac == expected_mac - - def test_long_mac_generating(self): - sas_alice = Sas() - sas_bob = Sas() - - with pytest.raises(OlmSasError): - sas_alice.calculate_mac_long_kdf(MESSAGE, EXTRA_INFO) - - sas_alice.set_their_pubkey(sas_bob.pubkey) - sas_bob.set_their_pubkey(sas_alice.pubkey) - - alice_mac = sas_alice.calculate_mac_long_kdf(MESSAGE, EXTRA_INFO) - bob_mac = sas_bob.calculate_mac_long_kdf(MESSAGE, EXTRA_INFO) - bob_short_mac = sas_bob.calculate_mac(MESSAGE, EXTRA_INFO) - - assert alice_mac == bob_mac - assert alice_mac != bob_short_mac diff --git a/python/tests/session_test.py b/python/tests/session_test.py deleted file mode 100644 index b856585..0000000 --- a/python/tests/session_test.py +++ /dev/null @@ -1,152 +0,0 @@ -# -*- coding: utf-8 -*- -import pytest - -from olm import (Account, InboundSession, OlmMessage, OlmPreKeyMessage, - OlmSessionError, OutboundSession, Session) - - -class TestClass(object): - def _create_session(self): - alice = Account() - bob = Account() - bob.generate_one_time_keys(1) - id_key = bob.identity_keys["curve25519"] - one_time = list(bob.one_time_keys["curve25519"].values())[0] - session = OutboundSession(alice, id_key, one_time) - return alice, bob, session - - def test_session_create(self): - _, _, session_1 = self._create_session() - _, _, session_2 = self._create_session() - assert session_1 - assert session_2 - assert session_1.id != session_2.id - assert isinstance(session_1.id, str) - - def test_session_clear(self): - _, _, session = self._create_session() - del session - - def test_invalid_session_create(self): - with pytest.raises(TypeError): - Session() - - def test_session_pickle(self): - alice, bob, session = self._create_session() - Session.from_pickle(session.pickle()).id == session.id - - def test_session_invalid_pickle(self): - with pytest.raises(ValueError): - Session.from_pickle(b"") - - def test_wrong_passphrase_pickle(self): - alice, bob, session = self._create_session() - passphrase = "It's a secret to everybody" - pickle = alice.pickle(passphrase) - - with pytest.raises(OlmSessionError): - Session.from_pickle(pickle, "") - - def test_encrypt(self): - plaintext = "It's a secret to everybody" - alice, bob, session = self._create_session() - message = session.encrypt(plaintext) - - assert (repr(message) - == "OlmPreKeyMessage({})".format(message.ciphertext)) - - assert (str(message) - == "PRE_KEY {}".format(message.ciphertext)) - - bob_session = InboundSession(bob, message) - assert plaintext == bob_session.decrypt(message) - - def test_empty_message(self): - with pytest.raises(ValueError): - OlmPreKeyMessage("") - empty = OlmPreKeyMessage("x") - empty.ciphertext = "" - alice, bob, session = self._create_session() - - with pytest.raises(ValueError): - session.decrypt(empty) - - def test_inbound_with_id(self): - plaintext = "It's a secret to everybody" - alice, bob, session = self._create_session() - message = session.encrypt(plaintext) - alice_id = alice.identity_keys["curve25519"] - bob_session = InboundSession(bob, message, alice_id) - assert plaintext == bob_session.decrypt(message) - - def test_two_messages(self): - plaintext = "It's a secret to everybody" - alice, bob, session = self._create_session() - message = session.encrypt(plaintext) - alice_id = alice.identity_keys["curve25519"] - bob_session = InboundSession(bob, message, alice_id) - bob.remove_one_time_keys(bob_session) - assert plaintext == bob_session.decrypt(message) - - bob_plaintext = "Grumble, Grumble" - bob_message = bob_session.encrypt(bob_plaintext) - - assert (repr(bob_message) - == "OlmMessage({})".format(bob_message.ciphertext)) - - assert bob_plaintext == session.decrypt(bob_message) - - def test_matches(self): - plaintext = "It's a secret to everybody" - alice, bob, session = self._create_session() - message = session.encrypt(plaintext) - alice_id = alice.identity_keys["curve25519"] - bob_session = InboundSession(bob, message, alice_id) - assert plaintext == bob_session.decrypt(message) - - message_2nd = session.encrypt("Hey! Listen!") - - assert bob_session.matches(message_2nd) is True - assert bob_session.matches(message_2nd, alice_id) is True - - def test_invalid(self): - alice, bob, session = self._create_session() - message = OlmMessage("x") - - with pytest.raises(TypeError): - session.matches(message) - - message = OlmPreKeyMessage("x") - message.ciphertext = "" - - with pytest.raises(ValueError): - session.matches(message) - - with pytest.raises(ValueError): - InboundSession(bob, message) - - with pytest.raises(ValueError): - OutboundSession(alice, "", "x") - - with pytest.raises(ValueError): - OutboundSession(alice, "x", "") - - def test_doesnt_match(self): - plaintext = "It's a secret to everybody" - alice, bob, session = self._create_session() - message = session.encrypt(plaintext) - alice_id = alice.identity_keys["curve25519"] - bob_session = InboundSession(bob, message, alice_id) - - _, _, new_session = self._create_session() - - new_message = new_session.encrypt(plaintext) - assert bob_session.matches(new_message) is False - - def test_invalid_unicode_decrypt(self): - alice, bob, session = self._create_session() - message = session.encrypt(b"\xed") - - bob_session = InboundSession(bob, message) - plaintext = bob_session.decrypt(message) - assert plaintext == u"�" diff --git a/python/tests/utils_test.py b/python/tests/utils_test.py deleted file mode 100644 index 86fb34f..0000000 --- a/python/tests/utils_test.py +++ /dev/null @@ -1,25 +0,0 @@ -import base64 -import hashlib - -from future.utils import bytes_to_native_str - -from olm import sha256 -from olm._compat import to_bytes - - -class TestClass(object): - def test_sha256(self): - input1 = "It's a secret to everybody" - input2 = "It's a secret to nobody" - - first_hash = sha256(input1) - second_hash = sha256(input2) - - hashlib_hash = base64.b64encode( - hashlib.sha256(to_bytes(input1)).digest() - ) - - hashlib_hash = bytes_to_native_str(hashlib_hash[:-1]) - - assert first_hash != second_hash - assert hashlib_hash == first_hash diff --git a/python/tox.ini b/python/tox.ini deleted file mode 100644 index e3a0188..0000000 --- a/python/tox.ini +++ /dev/null @@ -1,43 +0,0 @@ -# content of: tox.ini , put in same dir as setup.py -[tox] -envlist = py27,py36,pypy,{py2,py3}-cov,coverage -[testenv] -basepython = - py27: python2.7 - py36: python3.6 - pypy: pypy - py2: python2.7 - py3: python3.6 - -deps = -rrequirements.txt - -rtest-requirements.txt - -passenv = TOXENV CI TRAVIS TRAVIS_* -commands = pytest --benchmark-disable -usedevelop = True - -[testenv:py2-cov] -commands = - pytest --cov-report term-missing --cov=olm --benchmark-disable --cov-branch -setenv = - COVERAGE_FILE=.coverage.py2 - -[testenv:py3-cov] -commands = - py.test --cov=olm --cov-report term-missing --benchmark-disable --cov-branch -setenv = - COVERAGE_FILE=.coverage.py3 - -[testenv:coverage] -basepython = python3.6 -commands = - coverage erase - coverage combine - coverage xml - coverage report --show-missing - codecov -e TOXENV -deps = - coverage - codecov>=1.4.0 -setenv = - COVERAGE_FILE=.coverage diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt deleted file mode 100644 index 332da12..0000000 --- a/tests/CMakeLists.txt +++ /dev/null @@ -1,47 +0,0 @@ -enable_testing() - -set(TEST_LIST - test_base64 - test_crypto - test_group_session - test_list - test_megolm - test_message - test_olm - test_olm_decrypt - test_olm_sha256 - test_olm_signature - test_olm_using_malloc - test_session - test_pk - test_sas - ) - -if(NOT (${CMAKE_SYSTEM_NAME} MATCHES "Windows" AND BUILD_SHARED_LIBS)) - # test_ratchet doesn't work on Windows when building a DLL, because it tries - # to use internal symbols, so only enable it if we're not on Windows, or if - # we're building statically - set(TEST_LIST ${TEST_LIST} test_ratchet) - add_test(Ratchet test_ratchet) -endif() - -foreach(test IN ITEMS ${TEST_LIST}) -add_executable(${test} ${test}.cpp) -target_include_directories(${test} PRIVATE include) -target_link_libraries(${test} Olm::Olm) -endforeach(test) - -add_test(Base64 test_base64) -add_test(Crypto test_crypto) -add_test(GroupSession test_group_session) -add_test(List test_list) -add_test(Megolm test_megolm) -add_test(Message test_message) -add_test(Olm test_olm) -add_test(OlmDecrypt test_olm_decrypt) -add_test(OlmSha256 test_olm_sha256) -add_test(OlmSignature test_olm_signature) -add_test(OlmUsingMalloc test_olm_using_malloc) -add_test(Session test_session) -add_test(PublicKey test_session) -add_test(SAS test_sas) diff --git a/tests/include/unittest.hh b/tests/include/unittest.hh deleted file mode 100644 index 3ce4f38..0000000 --- a/tests/include/unittest.hh +++ /dev/null @@ -1,107 +0,0 @@ -/* Copyright 2015 OpenMarket Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <cstring> -#include <iostream> -#include <iomanip> -#include <cstdlib> -#include <string> - -std::ostream & print_hex( - std::ostream & os, - std::uint8_t const * data, - std::size_t length -) { - for (std::size_t i = 0; i < length; i++) { - os << std::setw(2) << std::setfill('0') << std::right - << std::hex << (int) data[i]; - } - return os; -} - - -char const * TEST_CASE; - - -template<typename T> -void assert_equals( - const char *file, - unsigned line, - const char *expected_expr, - const char *actual_expr, - T const & expected, - T const & actual -) { - if (expected != actual) { - std::cout << "FAILED: " << TEST_CASE << std::endl; - std::cout << file << ":" << line << std::endl; - std::cout << expected_expr << " == " << actual_expr << std::endl; - std::cout << "Expected: " << expected << std::endl; - std::cout << "Actual: " << actual << std::endl; - std::exit(1); - } -} - -template<typename T> -void assert_not_equals( - const char *file, - unsigned line, - const char *expected_expr, - const char *actual_expr, - T const & expected, - T const & actual -) { - if (expected == actual) { - std::cout << "FAILED: " << TEST_CASE << std::endl; - std::cout << file << ":" << line << std::endl; - std::cout << expected_expr << " == " << actual_expr << std::endl; - std::cout << "Unexpected: " << expected << std::endl; - std::cout << "Actual: " << actual << std::endl; - std::exit(1); - } -} - - -void assert_equals( - const char *file, - unsigned line, - const char *expected_expr, - const char *actual_expr, - std::uint8_t const * expected, - std::uint8_t const * actual, - std::size_t length -) { - if (std::memcmp(expected, actual, length)) { - std::cout << "FAILED: " << TEST_CASE << std::endl; - std::cout << file << ":" << line << std::endl; - std::cout << expected_expr << " == " << actual_expr << std::endl; - print_hex(std::cout << "Expected: ", expected, length) << std::endl; - print_hex(std::cout << "Actual: ", actual, length) << std::endl; - std::exit(1); - } -} - -#define assert_equals(expected, actual, ...) assert_equals( \ - __FILE__, __LINE__, #expected, #actual, expected, actual, ##__VA_ARGS__ \ -) - -#define assert_not_equals(expected, actual, ...) assert_not_equals( \ - __FILE__, __LINE__, #expected, #actual, expected, actual, ##__VA_ARGS__ \ -) - -class TestCase { -public: - TestCase(const char *name) { TEST_CASE = name; } - ~TestCase() { std::cout << "PASSED: " << TEST_CASE << std::endl; } -}; diff --git a/tests/test_base64.cpp b/tests/test_base64.cpp deleted file mode 100644 index 6f80acf..0000000 --- a/tests/test_base64.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "olm/base64.hh" -#include "olm/base64.h" -#include "unittest.hh" - -int main() { - -{ /* Base64 encode test */ -TestCase test_case("Base64 C++ binding encode test"); - -std::uint8_t input[] = "Hello World"; -std::uint8_t expected_output[] = "SGVsbG8gV29ybGQ"; -std::size_t input_length = sizeof(input) - 1; - -std::size_t output_length = olm::encode_base64_length(input_length); -assert_equals(std::size_t(15), output_length); - -std::uint8_t output[15]; -olm::encode_base64(input, input_length, output); -assert_equals(expected_output, output, output_length); -} - -{ -TestCase test_case("Base64 C binding encode test"); - -std::uint8_t input[] = "Hello World"; -std::uint8_t expected_output[] = "SGVsbG8gV29ybGQ"; -std::size_t input_length = sizeof(input) - 1; - -std::size_t output_length = ::_olm_encode_base64_length(input_length); -assert_equals(std::size_t(15), output_length); - -std::uint8_t output[15]; -output_length = ::_olm_encode_base64(input, input_length, output); -assert_equals(std::size_t(15), output_length); -assert_equals(expected_output, output, output_length); -} - -{ /* Base64 decode test */ -TestCase test_case("Base64 C++ binding decode test"); - -std::uint8_t input[] = "SGVsbG8gV29ybGQ"; -std::uint8_t expected_output[] = "Hello World"; -std::size_t input_length = sizeof(input) - 1; - -std::size_t output_length = olm::decode_base64_length(input_length); -assert_equals(std::size_t(11), output_length); - -std::uint8_t output[11]; -olm::decode_base64(input, input_length, output); -assert_equals(expected_output, output, output_length); -} - -{ -TestCase test_case("Base64 C binding decode test"); - -std::uint8_t input[] = "SGVsbG8gV29ybGQ"; -std::uint8_t expected_output[] = "Hello World"; -std::size_t input_length = sizeof(input) - 1; - -std::size_t output_length = ::_olm_decode_base64_length(input_length); -assert_equals(std::size_t(11), output_length); - -std::uint8_t output[11]; -output_length = ::_olm_decode_base64(input, input_length, output); -assert_equals(std::size_t(11), output_length); -assert_equals(expected_output, output, output_length); -} - - -} diff --git a/tests/test_crypto.cpp b/tests/test_crypto.cpp deleted file mode 100644 index 5da742c..0000000 --- a/tests/test_crypto.cpp +++ /dev/null @@ -1,252 +0,0 @@ -/* Copyright 2015 OpenMarket Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "olm/crypto.h" - -#include "unittest.hh" - -int main() { - - -{ /* Curve25529 Test Case 1 */ - -TestCase test_case("Curve25529 Test Case 1"); - -std::uint8_t alice_private[32] = { - 0x77, 0x07, 0x6D, 0x0A, 0x73, 0x18, 0xA5, 0x7D, - 0x3C, 0x16, 0xC1, 0x72, 0x51, 0xB2, 0x66, 0x45, - 0xDF, 0x4C, 0x2F, 0x87, 0xEB, 0xC0, 0x99, 0x2A, - 0xB1, 0x77, 0xFB, 0xA5, 0x1D, 0xB9, 0x2C, 0x2A -}; - -std::uint8_t alice_public[32] = { - 0x85, 0x20, 0xF0, 0x09, 0x89, 0x30, 0xA7, 0x54, - 0x74, 0x8B, 0x7D, 0xDC, 0xB4, 0x3E, 0xF7, 0x5A, - 0x0D, 0xBF, 0x3A, 0x0D, 0x26, 0x38, 0x1A, 0xF4, - 0xEB, 0xA4, 0xA9, 0x8E, 0xAA, 0x9B, 0x4E, 0x6A -}; - -std::uint8_t bob_private[32] = { - 0x5D, 0xAB, 0x08, 0x7E, 0x62, 0x4A, 0x8A, 0x4B, - 0x79, 0xE1, 0x7F, 0x8B, 0x83, 0x80, 0x0E, 0xE6, - 0x6F, 0x3B, 0xB1, 0x29, 0x26, 0x18, 0xB6, 0xFD, - 0x1C, 0x2F, 0x8B, 0x27, 0xFF, 0x88, 0xE0, 0xEB -}; - -std::uint8_t bob_public[32] = { - 0xDE, 0x9E, 0xDB, 0x7D, 0x7B, 0x7D, 0xC1, 0xB4, - 0xD3, 0x5B, 0x61, 0xC2, 0xEC, 0xE4, 0x35, 0x37, - 0x3F, 0x83, 0x43, 0xC8, 0x5B, 0x78, 0x67, 0x4D, - 0xAD, 0xFC, 0x7E, 0x14, 0x6F, 0x88, 0x2B, 0x4F -}; - -std::uint8_t expected_agreement[32] = { - 0x4A, 0x5D, 0x9D, 0x5B, 0xA4, 0xCE, 0x2D, 0xE1, - 0x72, 0x8E, 0x3B, 0xF4, 0x80, 0x35, 0x0F, 0x25, - 0xE0, 0x7E, 0x21, 0xC9, 0x47, 0xD1, 0x9E, 0x33, - 0x76, 0xF0, 0x9B, 0x3C, 0x1E, 0x16, 0x17, 0x42 -}; - -_olm_curve25519_key_pair alice_pair; -_olm_crypto_curve25519_generate_key(alice_private, &alice_pair); - -assert_equals(alice_private, alice_pair.private_key.private_key, 32); -assert_equals(alice_public, alice_pair.public_key.public_key, 32); - -_olm_curve25519_key_pair bob_pair; -_olm_crypto_curve25519_generate_key(bob_private, &bob_pair); - -assert_equals(bob_private, bob_pair.private_key.private_key, 32); -assert_equals(bob_public, bob_pair.public_key.public_key, 32); - -std::uint8_t actual_agreement[CURVE25519_SHARED_SECRET_LENGTH] = {}; - -_olm_crypto_curve25519_shared_secret(&alice_pair, &bob_pair.public_key, actual_agreement); - -assert_equals(expected_agreement, actual_agreement, 32); - -_olm_crypto_curve25519_shared_secret(&bob_pair, &alice_pair.public_key, actual_agreement); - -assert_equals(expected_agreement, actual_agreement, 32); - -} /* Curve25529 Test Case 1 */ - - -{ -TestCase test_case("Ed25519 Signature Test Case 1"); -std::uint8_t private_key[33] = "This key is a string of 32 bytes"; - -std::uint8_t message[] = "Hello, World"; -std::size_t message_length = sizeof(message) - 1; - -_olm_ed25519_key_pair key_pair; -_olm_crypto_ed25519_generate_key(private_key, &key_pair); - -std::uint8_t signature[64]; -_olm_crypto_ed25519_sign( - &key_pair, message, message_length, signature -); - -bool result = _olm_crypto_ed25519_verify( - &key_pair.public_key, message, message_length, signature -); -assert_equals(true, result); - -message[0] = 'n'; -result = _olm_crypto_ed25519_verify( - &key_pair.public_key, message, message_length, signature -); -assert_equals(false, result); -} - - -{ /* AES Test Case 1 */ - -TestCase test_case("AES Test Case 1"); - -_olm_aes256_key key = {}; -_olm_aes256_iv iv = {}; -std::uint8_t input[16] = {}; - -std::uint8_t expected[32] = { - 0xDC, 0x95, 0xC0, 0x78, 0xA2, 0x40, 0x89, 0x89, - 0xAD, 0x48, 0xA2, 0x14, 0x92, 0x84, 0x20, 0x87, - 0xF3, 0xC0, 0x03, 0xDD, 0xC4, 0xA7, 0xB8, 0xA9, - 0x4B, 0xAE, 0xDF, 0xFC, 0x3D, 0x21, 0x4C, 0x38 -}; - -std::size_t length = _olm_crypto_aes_encrypt_cbc_length(sizeof(input)); -assert_equals(std::size_t(32), length); - - -std::uint8_t actual[32] = {}; - -_olm_crypto_aes_encrypt_cbc(&key, &iv, input, sizeof(input), actual); -assert_equals(expected, actual, 32); - -length = _olm_crypto_aes_decrypt_cbc(&key, &iv, expected, sizeof(expected), actual); -assert_equals(std::size_t(16), length); -assert_equals(input, actual, length); - -} /* AES Test Case 1 */ - - -{ /* SHA 256 Test Case 1 */ - -TestCase test_case("SHA 256 Test Case 1"); - -// we want to take the hash of the empty string, but MSVC doesn't like -// allocating 0 bytes, so allocate one item, but pass a length of zero to -// sha256 -std::uint8_t input[1] = {0}; - -std::uint8_t expected[32] = { - 0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, - 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24, - 0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, - 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55 -}; - -std::uint8_t actual[32]; - -_olm_crypto_sha256(input, 0, actual); - -assert_equals(expected, actual, 32); - -} /* SHA 256 Test Case 1 */ - -{ /* HMAC Test Case 1 */ - -TestCase test_case("HMAC Test Case 1"); - -// we want to take the hash of the empty string, but MSVC doesn't like -// allocating 0 bytes, so allocate one item, but pass a length of zero to -// hmac_sha256 -std::uint8_t input[1] = {0}; - -std::uint8_t expected[32] = { - 0xb6, 0x13, 0x67, 0x9a, 0x08, 0x14, 0xd9, 0xec, - 0x77, 0x2f, 0x95, 0xd7, 0x78, 0xc3, 0x5f, 0xc5, - 0xff, 0x16, 0x97, 0xc4, 0x93, 0x71, 0x56, 0x53, - 0xc6, 0xc7, 0x12, 0x14, 0x42, 0x92, 0xc5, 0xad -}; - -std::uint8_t actual[32]; - -_olm_crypto_hmac_sha256(input, 0, input, 0, actual); - -assert_equals(expected, actual, 32); - -} /* HMAC Test Case 1 */ - -{ /* HDKF Test Case 1 */ - -TestCase test_case("HDKF Test Case 1"); - -std::uint8_t input[22] = { - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b -}; - -std::uint8_t salt[13] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c -}; - -std::uint8_t info[10] = { - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9 -}; - -std::uint8_t hmac_expected_output[32] = { - 0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf, - 0x0d, 0xdc, 0x3f, 0x0d, 0xc4, 0x7b, 0xba, 0x63, - 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f, 0x9c, 0x31, - 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5, -}; - -std::uint8_t hmac_actual_output[32] = {}; - -_olm_crypto_hmac_sha256( - salt, sizeof(salt), - input, sizeof(input), - hmac_actual_output -); - -assert_equals(hmac_expected_output, hmac_actual_output, 32); - -std::uint8_t hkdf_expected_output[42] = { - 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, - 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a, - 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c, - 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, - 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, - 0x58, 0x65 -}; - -std::uint8_t hkdf_actual_output[42] = {}; - -_olm_crypto_hkdf_sha256( - input, sizeof(input), - salt, sizeof(salt), - info, sizeof(info), - hkdf_actual_output, sizeof(hkdf_actual_output) -); - -assert_equals(hkdf_expected_output, hkdf_actual_output, 42); - -} /* HDKF Test Case 1 */ - -} diff --git a/tests/test_group_session.cpp b/tests/test_group_session.cpp deleted file mode 100644 index 19b7761..0000000 --- a/tests/test_group_session.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* 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. - */ -#include "olm/inbound_group_session.h" -#include "olm/outbound_group_session.h" -#include "unittest.hh" - -#include <vector> - -int main() { - -{ - TestCase test_case("Pickle outbound group session"); - - size_t size = olm_outbound_group_session_size(); - std::vector<uint8_t> memory(size); - OlmOutboundGroupSession *session = olm_outbound_group_session(memory.data()); - - size_t pickle_length = olm_pickle_outbound_group_session_length(session); - std::vector<uint8_t> pickle1(pickle_length); - size_t res = olm_pickle_outbound_group_session( - session, "secret_key", 10, pickle1.data(), pickle_length - ); - assert_equals(pickle_length, res); - - std::vector<uint8_t> pickle2(pickle1); - - std::vector<uint8_t> buffer2(size); - OlmOutboundGroupSession *session2 = olm_outbound_group_session(buffer2.data()); - res = olm_unpickle_outbound_group_session( - session2, "secret_key", 10, pickle2.data(), pickle_length - ); - assert_not_equals((size_t)-1, res); - assert_equals(pickle_length, - olm_pickle_outbound_group_session_length(session2)); - res = olm_pickle_outbound_group_session( - session2, "secret_key", 10, pickle2.data(), pickle_length - ); - assert_equals(pickle_length, res); - - assert_equals(pickle1.data(), pickle2.data(), pickle_length); -} - - -{ - TestCase test_case("Pickle inbound group session"); - - size_t size = olm_inbound_group_session_size(); - std::vector<uint8_t> memory(size); - OlmInboundGroupSession *session = olm_inbound_group_session(memory.data()); - - size_t pickle_length = olm_pickle_inbound_group_session_length(session); - std::vector<uint8_t> pickle1(pickle_length); - size_t res = olm_pickle_inbound_group_session( - session, "secret_key", 10, pickle1.data(), pickle_length - ); - assert_equals(pickle_length, res); - - std::vector<uint8_t> pickle2(pickle1); - - std::vector<uint8_t> buffer2(size); - OlmInboundGroupSession *session2 = olm_inbound_group_session(buffer2.data()); - res = olm_unpickle_inbound_group_session( - session2, "secret_key", 10, pickle2.data(), pickle_length - ); - assert_not_equals((size_t)-1, res); - assert_equals(pickle_length, - olm_pickle_inbound_group_session_length(session2)); - res = olm_pickle_inbound_group_session( - session2, "secret_key", 10, pickle2.data(), pickle_length - ); - - assert_equals(pickle1.data(), pickle2.data(), pickle_length); -} - -{ - TestCase test_case("Group message send/receive"); - - uint8_t random_bytes[] = - "0123456789ABDEF0123456789ABCDEF" - "0123456789ABDEF0123456789ABCDEF" - "0123456789ABDEF0123456789ABCDEF" - "0123456789ABDEF0123456789ABCDEF" - "0123456789ABDEF0123456789ABCDEF" - "0123456789ABDEF0123456789ABCDEF"; - - - /* build the outbound session */ - size_t size = olm_outbound_group_session_size(); - std::vector<uint8_t> memory(size); - OlmOutboundGroupSession *session = olm_outbound_group_session(memory.data()); - - assert_equals((size_t)160, - olm_init_outbound_group_session_random_length(session)); - - size_t res = olm_init_outbound_group_session( - session, random_bytes, sizeof(random_bytes)); - assert_equals((size_t)0, res); - - assert_equals(0U, olm_outbound_group_session_message_index(session)); - size_t session_key_len = olm_outbound_group_session_key_length(session); - std::vector<uint8_t> session_key(session_key_len); - olm_outbound_group_session_key(session, session_key.data(), session_key_len); - - /* encode the message */ - uint8_t plaintext[] = "Message"; - size_t plaintext_length = sizeof(plaintext) - 1; - - size_t msglen = olm_group_encrypt_message_length( - session, plaintext_length); - - std::vector<uint8_t> msg(msglen); - res = olm_group_encrypt(session, plaintext, plaintext_length, - msg.data(), msglen); - assert_equals(msglen, res); - assert_equals(1U, olm_outbound_group_session_message_index(session)); - - /* build the inbound session */ - size = olm_inbound_group_session_size(); - std::vector<uint8_t> inbound_session_memory(size); - OlmInboundGroupSession *inbound_session = - olm_inbound_group_session(inbound_session_memory.data()); - - assert_equals(0, olm_inbound_group_session_is_verified(inbound_session)); - - res = olm_init_inbound_group_session( - inbound_session, session_key.data(), session_key_len); - assert_equals((size_t)0, res); - assert_equals(1, olm_inbound_group_session_is_verified(inbound_session)); - - /* Check the session ids */ - - size_t out_session_id_len = olm_outbound_group_session_id_length(session); - std::vector<uint8_t> out_session_id(out_session_id_len); - assert_equals(out_session_id_len, olm_outbound_group_session_id( - session, out_session_id.data(), out_session_id_len - )); - - size_t in_session_id_len = olm_inbound_group_session_id_length( - inbound_session - ); - std::vector<uint8_t> in_session_id(in_session_id_len); - assert_equals(in_session_id_len, olm_inbound_group_session_id( - inbound_session, in_session_id.data(), in_session_id_len - )); - - assert_equals(in_session_id_len, out_session_id_len); - assert_equals(out_session_id.data(), in_session_id.data(), in_session_id_len); - - /* decode the message */ - - /* olm_group_decrypt_max_plaintext_length destroys the input so we have to - copy it. */ - std::vector<uint8_t> msgcopy(msg); - size = olm_group_decrypt_max_plaintext_length(inbound_session, msgcopy.data(), msglen); - std::vector<uint8_t> plaintext_buf(size); - uint32_t message_index; - res = olm_group_decrypt(inbound_session, msg.data(), msglen, - plaintext_buf.data(), size, &message_index); - assert_equals(plaintext_length, res); - assert_equals(plaintext, plaintext_buf.data(), res); - assert_equals(message_index, uint32_t(0)); -} - -{ - TestCase test_case("Inbound group session export/import"); - - uint8_t session_key[] = - "AgAAAAAwMTIzNDU2Nzg5QUJERUYwMTIzNDU2Nzg5QUJDREVGMDEyMzQ1Njc4OUFCREVGM" - "DEyMzQ1Njc4OUFCQ0RFRjAxMjM0NTY3ODlBQkRFRjAxMjM0NTY3ODlBQkNERUYwMTIzND" - "U2Nzg5QUJERUYwMTIzNDU2Nzg5QUJDREVGMDEyMw0bdg1BDq4Px/slBow06q8n/B9WBfw" - "WYyNOB8DlUmXGGwrFmaSb9bR/eY8xgERrxmP07hFmD9uqA2p8PMHdnV5ysmgufE6oLZ5+" - "8/mWQOW3VVTnDIlnwd8oHUYRuk8TCQ"; - - const uint8_t message[] = - "AwgAEhAcbh6UpbByoyZxufQ+h2B+8XHMjhR69G8F4+qjMaFlnIXusJZX3r8LnRORG9T3D" - "XFdbVuvIWrLyRfm4i8QRbe8VPwGRFG57B1CtmxanuP8bHtnnYqlwPsD"; - const std::size_t msglen = sizeof(message)-1; - - /* init first inbound group session, and decrypt */ - std::size_t size = olm_inbound_group_session_size(); - std::vector<uint8_t> session_memory1(size); - OlmInboundGroupSession *session1 = - olm_inbound_group_session(session_memory1.data()); - assert_equals(0, olm_inbound_group_session_is_verified(session1)); - - std::size_t res = olm_init_inbound_group_session( - session1, session_key, sizeof(session_key)-1 - ); - assert_equals((size_t)0, res); - assert_equals(1, olm_inbound_group_session_is_verified(session1)); - - /* olm_group_decrypt_max_plaintext_length destroys the input so we have to - copy it. */ - std::vector<uint8_t> msgcopy(msglen); - memcpy(msgcopy.data(), message, msglen); - size = olm_group_decrypt_max_plaintext_length(session1, msgcopy.data(), msglen); - std::vector<uint8_t> plaintext_buf(size); - uint32_t message_index; - memcpy(msgcopy.data(), message, msglen); - res = olm_group_decrypt( - session1, msgcopy.data(), msglen, plaintext_buf.data(), size, &message_index - ); - assert_equals((std::size_t)7, res); - assert_equals((const uint8_t *)"Message", plaintext_buf.data(), res); - assert_equals(uint32_t(0), message_index); - - /* export the keys */ - size = olm_export_inbound_group_session_length(session1); - std::vector<uint8_t> export_memory(size); - res = olm_export_inbound_group_session( - session1, export_memory.data(), size, 0 - ); - assert_equals(size, res); - - /* free the old session to check there is no shared data */ - olm_clear_inbound_group_session(session1); - - /* import the keys into another inbound group session */ - size = olm_inbound_group_session_size(); - std::vector<uint8_t> session_memory2(size); - OlmInboundGroupSession *session2 = - olm_inbound_group_session(session_memory2.data()); - res = olm_import_inbound_group_session( - session2, export_memory.data(), export_memory.size() - ); - assert_equals((size_t)0, res); - assert_equals(0, olm_inbound_group_session_is_verified(session2)); - - /* decrypt the message with the new session */ - memcpy(msgcopy.data(), message, msglen); - size = olm_group_decrypt_max_plaintext_length(session2, msgcopy.data(), msglen); - std::vector<uint8_t> plaintext_buf2(size); - memcpy(msgcopy.data(), message, msglen); - res = olm_group_decrypt( - session2, msgcopy.data(), msglen, plaintext_buf2.data(), size, &message_index - ); - assert_equals((std::size_t)7, res); - assert_equals((const uint8_t *)"Message", plaintext_buf2.data(), res); - assert_equals(uint32_t(0), message_index); - assert_equals(1, olm_inbound_group_session_is_verified(session2)); -} - -{ - TestCase test_case("Invalid signature group message"); - - uint8_t plaintext[] = "Message"; - size_t plaintext_length = sizeof(plaintext) - 1; - - uint8_t session_key[] = - "AgAAAAAwMTIzNDU2Nzg5QUJERUYwMTIzNDU2Nzg5QUJDREVGMDEyMzQ1Njc4OUFCREVGM" - "DEyMzQ1Njc4OUFCQ0RFRjAxMjM0NTY3ODlBQkRFRjAxMjM0NTY3ODlBQkNERUYwMTIzND" - "U2Nzg5QUJERUYwMTIzNDU2Nzg5QUJDREVGMDEyMztqJ7zOtqQtYqOo0CpvDXNlMhV3HeJ" - "DpjrASKGLWdop4lx1cSN3Xv1TgfLPW8rhGiW+hHiMxd36nRuxscNv9k4oJA/KP+o0mi1w" - "v44StrEJ1wwx9WZHBUIWkQbaBSuBDw"; - - uint8_t message[] = - "AwgAEhAcbh6UpbByoyZxufQ+h2B+8XHMjhR69G8nP4pNZGl/3QMgrzCZPmP+F2aPLyKPz" - "xRPBMUkeXRJ6Iqm5NeOdx2eERgTW7P20CM+lL3Xpk+ZUOOPvsSQNaAL"; - size_t msglen = sizeof(message)-1; - - /* build the inbound session */ - size_t size = olm_inbound_group_session_size(); - std::vector<uint8_t> inbound_session_memory(size); - OlmInboundGroupSession *inbound_session = - olm_inbound_group_session(inbound_session_memory.data()); - - size_t res = olm_init_inbound_group_session( - inbound_session, session_key, sizeof(session_key)-1 - ); - assert_equals((size_t)0, res); - - /* decode the message */ - - /* olm_group_decrypt_max_plaintext_length destroys the input so we have to - copy it. */ - std::vector<uint8_t> msgcopy(msglen); - memcpy(msgcopy.data(), message, msglen); - size = olm_group_decrypt_max_plaintext_length( - inbound_session, msgcopy.data(), msglen - ); - - memcpy(msgcopy.data(), message, msglen); - std::vector<uint8_t> plaintext_buf(size); - uint32_t message_index; - res = olm_group_decrypt( - inbound_session, msgcopy.data(), msglen, plaintext_buf.data(), size, &message_index - ); - assert_equals(message_index, uint32_t(0)); - assert_equals(plaintext_length, res); - assert_equals(plaintext, plaintext_buf.data(), res); - - /* now twiddle the signature */ - message[msglen-1] = 'E'; - memcpy(msgcopy.data(), message, msglen); - assert_equals( - size, - olm_group_decrypt_max_plaintext_length( - inbound_session, msgcopy.data(), msglen - ) - ); - - memcpy(msgcopy.data(), message, msglen); - res = olm_group_decrypt( - inbound_session, msgcopy.data(), msglen, - plaintext_buf.data(), size, &message_index - ); - assert_equals((size_t)-1, res); - assert_equals( - std::string("BAD_SIGNATURE"), - std::string(olm_inbound_group_session_last_error(inbound_session)) - ); -} - - -} diff --git a/tests/test_list.cpp b/tests/test_list.cpp deleted file mode 100644 index c054af6..0000000 --- a/tests/test_list.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright 2015 OpenMarket Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "olm/list.hh" -#include "unittest.hh" - -int main() { - -{ /** List insert test **/ - -TestCase test_case("List insert"); - -olm::List<int, 4> test_list; - -assert_equals(std::size_t(0), test_list.size()); - -for (int i = 0; i < 4; ++i) { - test_list.insert(test_list.end(), i); -} - -assert_equals(std::size_t(4), test_list.size()); - -int i = 0; -for (auto item : test_list) { - assert_equals(i++, item); -} - -assert_equals(4, i); - -test_list.insert(test_list.end(), 4); - -assert_equals(4, test_list[3]); - -} /** List insert test **/ - -{ /** List insert beginning test **/ - -TestCase test_case("List insert beginning"); - -olm::List<int, 4> test_list; - -assert_equals(std::size_t(0), test_list.size()); - -for (int i = 0; i < 4; ++i) { - test_list.insert(test_list.begin(), i); -} - -assert_equals(std::size_t(4), test_list.size()); - -int i = 4; -for (auto item : test_list) { - assert_equals(--i, item); -} - -} /** List insert test **/ - - -{ /** List erase test **/ -TestCase test_case("List erase"); - -olm::List<int, 4> test_list; -assert_equals(std::size_t(0), test_list.size()); - -for (int i = 0; i < 4; ++i) { - test_list.insert(test_list.end(), i); -} -assert_equals(std::size_t(4), test_list.size()); - -test_list.erase(test_list.begin()); -assert_equals(std::size_t(3), test_list.size()); - -int i = 0; -for (auto item : test_list) { - assert_equals(i + 1, item); - ++i; -} -assert_equals(3, i); - -} - -} diff --git a/tests/test_megolm.cpp b/tests/test_megolm.cpp deleted file mode 100644 index 3048fa3..0000000 --- a/tests/test_megolm.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* 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. - */ -#include "olm/megolm.h" -#include "olm/memory.hh" - -#include "unittest.hh" - - -int main() { - -std::uint8_t random_bytes[] = - "0123456789ABCDEF0123456789ABCDEF" - "0123456789ABCDEF0123456789ABCDEF" - "0123456789ABCDEF0123456789ABCDEF" - "0123456789ABCDEF0123456789ABCDEF"; - -{ - TestCase test_case("Megolm::advance"); - - Megolm mr; - - megolm_init(&mr, random_bytes, 0); - // single-step advance - megolm_advance(&mr); - const std::uint8_t expected1[] = { - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, - 0xba, 0x9c, 0xd9, 0x55, 0x74, 0x1d, 0x1c, 0x16, 0x23, 0x23, 0xec, 0x82, 0x5e, 0x7c, 0x5c, 0xe8, - 0x89, 0xbb, 0xb4, 0x23, 0xa1, 0x8f, 0x23, 0x82, 0x8f, 0xb2, 0x09, 0x0d, 0x6e, 0x2a, 0xf8, 0x6a - }; - assert_equals(1U, mr.counter); - assert_equals(expected1, megolm_get_data(&mr), MEGOLM_RATCHET_LENGTH); - - // repeat with complex advance - megolm_init(&mr, random_bytes, 0); - megolm_advance_to(&mr, 1); - assert_equals(1U, mr.counter); - assert_equals(expected1, megolm_get_data(&mr), MEGOLM_RATCHET_LENGTH); - - megolm_advance_to(&mr, 0x1000000); - const std::uint8_t expected2[] = { - 0x54, 0x02, 0x2d, 0x7d, 0xc0, 0x29, 0x8e, 0x16, 0x37, 0xe2, 0x1c, 0x97, 0x15, 0x30, 0x92, 0xf9, - 0x33, 0xc0, 0x56, 0xff, 0x74, 0xfe, 0x1b, 0x92, 0x2d, 0x97, 0x1f, 0x24, 0x82, 0xc2, 0x85, 0x9c, - 0x70, 0x04, 0xc0, 0x1e, 0xe4, 0x9b, 0xd6, 0xef, 0xe0, 0x07, 0x35, 0x25, 0xaf, 0x9b, 0x16, 0x32, - 0xc5, 0xbe, 0x72, 0x6d, 0x12, 0x34, 0x9c, 0xc5, 0xbd, 0x47, 0x2b, 0xdc, 0x2d, 0xf6, 0x54, 0x0f, - 0x31, 0x12, 0x59, 0x11, 0x94, 0xfd, 0xa6, 0x17, 0xe5, 0x68, 0xc6, 0x83, 0x10, 0x1e, 0xae, 0xcd, - 0x7e, 0xdd, 0xd6, 0xde, 0x1f, 0xbc, 0x07, 0x67, 0xae, 0x34, 0xda, 0x1a, 0x09, 0xa5, 0x4e, 0xab, - 0xba, 0x9c, 0xd9, 0x55, 0x74, 0x1d, 0x1c, 0x16, 0x23, 0x23, 0xec, 0x82, 0x5e, 0x7c, 0x5c, 0xe8, - 0x89, 0xbb, 0xb4, 0x23, 0xa1, 0x8f, 0x23, 0x82, 0x8f, 0xb2, 0x09, 0x0d, 0x6e, 0x2a, 0xf8, 0x6a, - }; - assert_equals(0x1000000U, mr.counter); - assert_equals(expected2, megolm_get_data(&mr), MEGOLM_RATCHET_LENGTH); - - megolm_advance_to(&mr, 0x1041506); - const std::uint8_t expected3[] = { - 0x54, 0x02, 0x2d, 0x7d, 0xc0, 0x29, 0x8e, 0x16, 0x37, 0xe2, 0x1c, 0x97, 0x15, 0x30, 0x92, 0xf9, - 0x33, 0xc0, 0x56, 0xff, 0x74, 0xfe, 0x1b, 0x92, 0x2d, 0x97, 0x1f, 0x24, 0x82, 0xc2, 0x85, 0x9c, - 0x55, 0x58, 0x8d, 0xf5, 0xb7, 0xa4, 0x88, 0x78, 0x42, 0x89, 0x27, 0x86, 0x81, 0x64, 0x58, 0x9f, - 0x36, 0x63, 0x44, 0x7b, 0x51, 0xed, 0xc3, 0x59, 0x5b, 0x03, 0x6c, 0xa6, 0x04, 0xc4, 0x6d, 0xcd, - 0x5c, 0x54, 0x85, 0x0b, 0xfa, 0x98, 0xa1, 0xfd, 0x79, 0xa9, 0xdf, 0x1c, 0xbe, 0x8f, 0xc5, 0x68, - 0x19, 0x37, 0xd3, 0x0c, 0x85, 0xc8, 0xc3, 0x1f, 0x7b, 0xb8, 0x28, 0x81, 0x6c, 0xf9, 0xff, 0x3b, - 0x95, 0x6c, 0xbf, 0x80, 0x7e, 0x65, 0x12, 0x6a, 0x49, 0x55, 0x8d, 0x45, 0xc8, 0x4a, 0x2e, 0x4c, - 0xd5, 0x6f, 0x03, 0xe2, 0x44, 0x16, 0xb9, 0x8e, 0x1c, 0xfd, 0x97, 0xc2, 0x06, 0xaa, 0x90, 0x7a - }; - assert_equals(0x1041506U, mr.counter); - assert_equals(expected3, megolm_get_data(&mr), MEGOLM_RATCHET_LENGTH); -} - -{ - TestCase test_case("Megolm::advance wraparound"); - - Megolm mr1, mr2; - - megolm_init(&mr1, random_bytes, 0xffffffffUL); - megolm_advance_to(&mr1, 0x1000000); - assert_equals(0x1000000U, mr1.counter); - - megolm_init(&mr2, random_bytes, 0); - megolm_advance_to(&mr2, 0x2000000); - assert_equals(0x2000000U, mr2.counter); - - assert_equals(megolm_get_data(&mr2), megolm_get_data(&mr1), MEGOLM_RATCHET_LENGTH); -} - -{ - TestCase test_case("Megolm::advance overflow by one"); - - Megolm mr1, mr2; - - megolm_init(&mr1, random_bytes, 0xffffffffUL); - megolm_advance_to(&mr1, 0x0); - assert_equals(0x0U, mr1.counter); - - megolm_init(&mr2, random_bytes, 0xffffffffUL); - megolm_advance(&mr2); - assert_equals(0x0U, mr2.counter); - - assert_equals(megolm_get_data(&mr2), megolm_get_data(&mr1), MEGOLM_RATCHET_LENGTH); -} - -{ - TestCase test_case("Megolm::advance overflow"); - - Megolm mr1, mr2; - - megolm_init(&mr1, random_bytes, 0x1UL); - megolm_advance_to(&mr1, 0x80000000UL); - megolm_advance_to(&mr1, 0x0); - assert_equals(0x0U, mr1.counter); - - megolm_init(&mr2, random_bytes, 0x1UL); - megolm_advance_to(&mr2, 0x0UL); - assert_equals(0x0U, mr2.counter); - - assert_equals(megolm_get_data(&mr2), megolm_get_data(&mr1), MEGOLM_RATCHET_LENGTH); -} - -} diff --git a/tests/test_message.cpp b/tests/test_message.cpp deleted file mode 100644 index fa2d0cc..0000000 --- a/tests/test_message.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* 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. - */ -#include "olm/message.hh" -#include "unittest.hh" - -int main() { - -std::uint8_t message1[36] = "\x03\x10\x01\n\nratchetkey\"\nciphertexthmacsha2"; -std::uint8_t message2[36] = "\x03\n\nratchetkey\x10\x01\"\nciphertexthmacsha2"; -std::uint8_t ratchetkey[11] = "ratchetkey"; -std::uint8_t ciphertext[11] = "ciphertext"; -std::uint8_t hmacsha2[9] = "hmacsha2"; - -{ /* Message decode test */ - -TestCase test_case("Message decode test"); - -olm::MessageReader reader; -olm::decode_message(reader, message1, 35, 8); - -assert_equals(std::uint8_t(3), reader.version); -assert_equals(true, reader.has_counter); -assert_equals(std::uint32_t(1), reader.counter); -assert_equals(std::size_t(10), reader.ratchet_key_length); -assert_equals(std::size_t(10), reader.ciphertext_length); - -assert_equals(ratchetkey, reader.ratchet_key, 10); -assert_equals(ciphertext, reader.ciphertext, 10); - - -} /* Message decode test */ - -{ /* Message encode test */ - -TestCase test_case("Message encode test"); - -std::size_t length = olm::encode_message_length(1, 10, 10, 8); -assert_equals(std::size_t(35), length); - -std::uint8_t output[35]; - -olm::MessageWriter writer; -olm::encode_message(writer, 3, 1, 10, 10, output); - -std::memcpy(writer.ratchet_key, ratchetkey, 10); -std::memcpy(writer.ciphertext, ciphertext, 10); -std::memcpy(output + length - 8, hmacsha2, 8); - -assert_equals(message2, output, 35); - -} /* Message encode test */ - - -{ /* group message encode test */ - - TestCase test_case("Group message encode test"); - - size_t length = _olm_encode_group_message_length(200, 10, 8, 64); - size_t expected_length = 1 + (1+2) + (2+10) + 8 + 64; - assert_equals(expected_length, length); - - uint8_t output[50]; - uint8_t *ciphertext_ptr; - - _olm_encode_group_message( - 3, - 200, // counter - 10, // ciphertext length - output, - &ciphertext_ptr - ); - - uint8_t expected[] = - "\x03" - "\x08\xC8\x01" - "\x12\x0A"; - - assert_equals(expected, output, sizeof(expected)-1); - assert_equals(output+sizeof(expected)-1, ciphertext_ptr); -} /* group message encode test */ - -{ - TestCase test_case("Group message decode test"); - - struct _OlmDecodeGroupMessageResults results; - std::uint8_t message[] = - "\x03" - "\x08\xC8\x01" - "\x12\x0A" "ciphertext" - "hmacsha2" - "ed25519signature"; - - _olm_decode_group_message(message, sizeof(message)-1, 8, 16, &results); - assert_equals(std::uint8_t(3), results.version); - assert_equals(1, results.has_message_index); - assert_equals(std::uint32_t(200), results.message_index); - assert_equals(std::size_t(10), results.ciphertext_length); - assert_equals(ciphertext, results.ciphertext, 10); -} /* group message decode test */ -} diff --git a/tests/test_olm.cpp b/tests/test_olm.cpp deleted file mode 100644 index ab7d816..0000000 --- a/tests/test_olm.cpp +++ /dev/null @@ -1,399 +0,0 @@ -#include "olm/olm.h" -#include "unittest.hh" - -#include <cstddef> -#include <cstdint> -#include <cstring> -#include <vector> - -struct MockRandom { - MockRandom(std::uint8_t tag, std::uint8_t offset = 0) - : tag(tag), current(offset) {} - void operator()( - std::uint8_t * bytes, std::size_t length - ) { - while (length > 32) { - bytes[0] = tag; - std::memset(bytes + 1, current, 31); - length -= 32; - bytes += 32; - current += 1; - } - if (length) { - bytes[0] = tag; - std::memset(bytes + 1, current, length - 1); - current += 1; - } - } - std::uint8_t tag; - std::uint8_t current; -}; - -int main() { - -{ /** Pickle account test */ - -TestCase test_case("Pickle account test"); -MockRandom mock_random('P'); - - -std::vector<std::uint8_t> account_buffer(::olm_account_size()); -::OlmAccount *account = ::olm_account(account_buffer.data()); -std::vector<std::uint8_t> random(::olm_create_account_random_length(account)); -mock_random(random.data(), random.size()); -::olm_create_account(account, random.data(), random.size()); -std::vector<std::uint8_t> ot_random(::olm_account_generate_one_time_keys_random_length( - account, 42 - )); -mock_random(ot_random.data(), ot_random.size()); -::olm_account_generate_one_time_keys(account, 42, ot_random.data(), ot_random.size()); - -std::size_t pickle_length = ::olm_pickle_account_length(account); -std::vector<std::uint8_t> pickle1(pickle_length); -std::size_t res = ::olm_pickle_account(account, "secret_key", 10, pickle1.data(), pickle_length); -assert_equals(pickle_length, res); - -std::vector<std::uint8_t> pickle2(pickle1); - -std::vector<std::uint8_t> account_buffer2(::olm_account_size()); -::OlmAccount *account2 = ::olm_account(account_buffer2.data()); -assert_not_equals(std::size_t(-1), ::olm_unpickle_account( - account2, "secret_key", 10, pickle2.data(), pickle_length -)); -assert_equals(pickle_length, ::olm_pickle_account_length(account2)); -res = ::olm_pickle_account(account2, "secret_key", 10, pickle2.data(), pickle_length); -assert_equals(pickle_length, res); - -assert_equals(pickle1.data(), pickle2.data(), pickle_length); -} - - -{ - TestCase test_case("Old account unpickle test"); - - // this uses the old pickle format, which did not use enough space - // for the Ed25519 key. We should reject it. - std::uint8_t pickle[] = - "x3h9er86ygvq56pM1yesdAxZou4ResPQC9Rszk/fhEL9JY/umtZ2N/foL/SUgVXS" - "v0IxHHZTafYjDdzJU9xr8dQeBoOTGfV9E/lCqDGBnIlu7SZndqjEKXtzGyQr4sP4" - "K/A/8TOu9iK2hDFszy6xETiousHnHgh2ZGbRUh4pQx+YMm8ZdNZeRnwFGLnrWyf9" - "O5TmXua1FcU"; - - std::vector<std::uint8_t> account_buffer(::olm_account_size()); - ::OlmAccount *account = ::olm_account(account_buffer.data()); - assert_equals( - std::size_t(-1), - ::olm_unpickle_account( - account, "", 0, pickle, sizeof(pickle)-1 - ) - ); - assert_equals( - std::string("BAD_LEGACY_ACCOUNT_PICKLE"), - std::string(::olm_account_last_error(account)) - ); -} - - -{ /** Pickle session test */ - -TestCase test_case("Pickle session test"); -MockRandom mock_random('P'); - -std::vector<std::uint8_t> account_buffer(::olm_account_size()); -::OlmAccount *account = ::olm_account(account_buffer.data()); -std::vector<std::uint8_t> random(::olm_create_account_random_length(account)); -mock_random(random.data(), random.size()); -::olm_create_account(account, random.data(), random.size()); - -std::vector<std::uint8_t> session_buffer(::olm_session_size()); -::OlmSession *session = ::olm_session(session_buffer.data()); -std::uint8_t identity_key[32]; -std::uint8_t one_time_key[32]; -mock_random(identity_key, sizeof(identity_key)); -mock_random(one_time_key, sizeof(one_time_key)); -std::vector<std::uint8_t> random2(::olm_create_outbound_session_random_length(session)); -mock_random(random2.data(), random2.size()); - -::olm_create_outbound_session( - session, account, - identity_key, sizeof(identity_key), - one_time_key, sizeof(one_time_key), - random2.data(), random2.size() -); - - -std::size_t pickle_length = ::olm_pickle_session_length(session); -std::vector<std::uint8_t> pickle1(pickle_length); -std::size_t res = ::olm_pickle_session(session, "secret_key", 10, pickle1.data(), pickle_length); -assert_equals(pickle_length, res); - -std::vector<std::uint8_t> pickle2(pickle1); - -std::vector<std::uint8_t> session_buffer2(::olm_session_size()); -::OlmSession *session2 = ::olm_session(session_buffer2.data()); -assert_not_equals(std::size_t(-1), ::olm_unpickle_session( - session2, "secret_key", 10, pickle2.data(), pickle_length -)); -assert_equals(pickle_length, ::olm_pickle_session_length(session2)); -res = ::olm_pickle_session(session2, "secret_key", 10, pickle2.data(), pickle_length); -assert_equals(pickle_length, res); - -assert_equals(pickle1.data(), pickle2.data(), pickle_length); -} - -{ /** Loopback test */ - -TestCase test_case("Loopback test"); -MockRandom mock_random_a('A', 0x00); -MockRandom mock_random_b('B', 0x80); - -std::vector<std::uint8_t> a_account_buffer(::olm_account_size()); -::OlmAccount *a_account = ::olm_account(a_account_buffer.data()); -std::vector<std::uint8_t> a_random(::olm_create_account_random_length(a_account)); -mock_random_a(a_random.data(), a_random.size()); -::olm_create_account(a_account, a_random.data(), a_random.size()); - -std::vector<std::uint8_t> b_account_buffer(::olm_account_size()); -::OlmAccount *b_account = ::olm_account(b_account_buffer.data()); -std::vector<std::uint8_t> b_random(::olm_create_account_random_length(b_account)); -mock_random_b(b_random.data(), b_random.size()); -::olm_create_account(b_account, b_random.data(), b_random.size()); -std::vector<std::uint8_t> o_random(::olm_account_generate_one_time_keys_random_length( - b_account, 42 -)); -mock_random_b(o_random.data(), o_random.size()); -::olm_account_generate_one_time_keys(b_account, 42, o_random.data(), o_random.size()); - -std::vector<std::uint8_t> a_id_keys(::olm_account_identity_keys_length(a_account)); -::olm_account_identity_keys(a_account, a_id_keys.data(), a_id_keys.size()); - -std::vector<std::uint8_t> b_id_keys(::olm_account_identity_keys_length(b_account)); -std::vector<std::uint8_t> b_ot_keys(::olm_account_one_time_keys_length(b_account)); -::olm_account_identity_keys(b_account, b_id_keys.data(), b_id_keys.size()); -::olm_account_one_time_keys(b_account, b_ot_keys.data(), b_ot_keys.size()); - -std::vector<std::uint8_t> a_session_buffer(::olm_session_size()); -::OlmSession *a_session = ::olm_session(a_session_buffer.data()); -std::vector<std::uint8_t> a_rand(::olm_create_outbound_session_random_length(a_session)); -mock_random_a(a_rand.data(), a_rand.size()); -assert_not_equals(std::size_t(-1), ::olm_create_outbound_session( - a_session, a_account, - b_id_keys.data() + 15, 43, // B's curve25519 identity key - b_ot_keys.data() + 25, 43, // B's curve25519 one time key - a_rand.data(), a_rand.size() -)); - -std::uint8_t plaintext[] = "Hello, World"; -std::vector<std::uint8_t> message_1(::olm_encrypt_message_length(a_session, 12)); -std::vector<std::uint8_t> a_message_random(::olm_encrypt_random_length(a_session)); -mock_random_a(a_message_random.data(), a_message_random.size()); -assert_equals(std::size_t(0), ::olm_encrypt_message_type(a_session)); -assert_not_equals(std::size_t(-1), ::olm_encrypt( - a_session, - plaintext, 12, - a_message_random.data(), a_message_random.size(), - message_1.data(), message_1.size() -)); - - -std::vector<std::uint8_t> tmp_message_1(message_1); -std::vector<std::uint8_t> b_session_buffer(::olm_account_size()); -::OlmSession *b_session = ::olm_session(b_session_buffer.data()); -::olm_create_inbound_session( - b_session, b_account, tmp_message_1.data(), message_1.size() -); - -// Check that the inbound session matches the message it was created from. -std::memcpy(tmp_message_1.data(), message_1.data(), message_1.size()); -assert_equals(std::size_t(1), ::olm_matches_inbound_session( - b_session, - tmp_message_1.data(), message_1.size() -)); - -// Check that the inbound session matches the key this message is supposed -// to be from. -std::memcpy(tmp_message_1.data(), message_1.data(), message_1.size()); -assert_equals(std::size_t(1), ::olm_matches_inbound_session_from( - b_session, - a_id_keys.data() + 15, 43, // A's curve125519 identity key. - tmp_message_1.data(), message_1.size() -)); - -// Check that the inbound session isn't from a different user. -std::memcpy(tmp_message_1.data(), message_1.data(), message_1.size()); -assert_equals(std::size_t(0), ::olm_matches_inbound_session_from( - b_session, - b_id_keys.data() + 15, 43, // B's curve25519 identity key. - tmp_message_1.data(), message_1.size() -)); - -// Check that we can decrypt the message. -std::memcpy(tmp_message_1.data(), message_1.data(), message_1.size()); -std::vector<std::uint8_t> plaintext_1(::olm_decrypt_max_plaintext_length( - b_session, 0, tmp_message_1.data(), message_1.size() -)); -std::memcpy(tmp_message_1.data(), message_1.data(), message_1.size()); -assert_equals(std::size_t(12), ::olm_decrypt( - b_session, 0, - tmp_message_1.data(), message_1.size(), - plaintext_1.data(), plaintext_1.size() -)); - -assert_equals(plaintext, plaintext_1.data(), 12); - -std::vector<std::uint8_t> message_2(::olm_encrypt_message_length(b_session, 12)); -std::vector<std::uint8_t> b_message_random(::olm_encrypt_random_length(b_session)); -mock_random_b(b_message_random.data(), b_message_random.size()); -assert_equals(std::size_t(1), ::olm_encrypt_message_type(b_session)); -assert_not_equals(std::size_t(-1), ::olm_encrypt( - b_session, - plaintext, 12, - b_message_random.data(), b_message_random.size(), - message_2.data(), message_2.size() -)); - -std::vector<std::uint8_t> tmp_message_2(message_2); -std::vector<std::uint8_t> plaintext_2(::olm_decrypt_max_plaintext_length( - a_session, 1, tmp_message_2.data(), message_2.size() -)); -std::memcpy(tmp_message_2.data(), message_2.data(), message_2.size()); -assert_equals(std::size_t(12), ::olm_decrypt( - a_session, 1, - tmp_message_2.data(), message_2.size(), - plaintext_2.data(), plaintext_2.size() -)); - -assert_equals(plaintext, plaintext_2.data(), 12); - -std::memcpy(tmp_message_2.data(), message_2.data(), message_2.size()); -assert_equals(std::size_t(-1), ::olm_decrypt( - a_session, 1, - tmp_message_2.data(), message_2.size(), - plaintext_2.data(), plaintext_2.size() -)); - -std::vector<std::uint8_t> a_session_id(::olm_session_id_length(a_session)); -assert_not_equals(std::size_t(-1), ::olm_session_id( - a_session, a_session_id.data(), a_session_id.size() -)); - -std::vector<std::uint8_t> b_session_id(::olm_session_id_length(b_session)); -assert_not_equals(std::size_t(-1), ::olm_session_id( - b_session, b_session_id.data(), b_session_id.size() -)); - -assert_equals(a_session_id.size(), b_session_id.size()); -assert_equals(a_session_id.data(), b_session_id.data(), b_session_id.size()); - -} - -{ /** More messages test */ - -TestCase test_case("More messages test"); -MockRandom mock_random_a('A', 0x00); -MockRandom mock_random_b('B', 0x80); - -std::vector<std::uint8_t> a_account_buffer(::olm_account_size()); -::OlmAccount *a_account = ::olm_account(a_account_buffer.data()); -std::vector<std::uint8_t> a_random(::olm_create_account_random_length(a_account)); -mock_random_a(a_random.data(), a_random.size()); -::olm_create_account(a_account, a_random.data(), a_random.size()); - -std::vector<std::uint8_t> b_account_buffer(::olm_account_size()); -::OlmAccount *b_account = ::olm_account(b_account_buffer.data()); -std::vector<std::uint8_t> b_random(::olm_create_account_random_length(b_account)); -mock_random_b(b_random.data(), b_random.size()); -::olm_create_account(b_account, b_random.data(), b_random.size()); -std::vector<std::uint8_t> o_random(::olm_account_generate_one_time_keys_random_length( - b_account, 42 -)); -mock_random_b(o_random.data(), o_random.size()); -::olm_account_generate_one_time_keys(b_account, 42, o_random.data(), o_random.size()); - -std::vector<std::uint8_t> b_id_keys(::olm_account_identity_keys_length(b_account)); -std::vector<std::uint8_t> b_ot_keys(::olm_account_one_time_keys_length(b_account)); -::olm_account_identity_keys(b_account, b_id_keys.data(), b_id_keys.size()); -::olm_account_one_time_keys(b_account, b_ot_keys.data(), b_ot_keys.size()); - -std::vector<std::uint8_t> a_session_buffer(::olm_session_size()); -::OlmSession *a_session = ::olm_session(a_session_buffer.data()); -std::vector<std::uint8_t> a_rand(::olm_create_outbound_session_random_length(a_session)); -mock_random_a(a_rand.data(), a_rand.size()); -assert_not_equals(std::size_t(-1), ::olm_create_outbound_session( - a_session, a_account, - b_id_keys.data() + 15, 43, - b_ot_keys.data() + 25, 43, - a_rand.data(), a_rand.size() -)); - -std::uint8_t plaintext[] = "Hello, World"; -std::vector<std::uint8_t> message_1(::olm_encrypt_message_length(a_session, 12)); -std::vector<std::uint8_t> a_message_random(::olm_encrypt_random_length(a_session)); -mock_random_a(a_message_random.data(), a_message_random.size()); -assert_equals(std::size_t(0), ::olm_encrypt_message_type(a_session)); -assert_not_equals(std::size_t(-1), ::olm_encrypt( - a_session, - plaintext, 12, - a_message_random.data(), a_message_random.size(), - message_1.data(), message_1.size() -)); - -std::vector<std::uint8_t> tmp_message_1(message_1); -std::vector<std::uint8_t> b_session_buffer(::olm_account_size()); -::OlmSession *b_session = ::olm_session(b_session_buffer.data()); -::olm_create_inbound_session( - b_session, b_account, tmp_message_1.data(), message_1.size() -); - -std::memcpy(tmp_message_1.data(), message_1.data(), message_1.size()); -std::vector<std::uint8_t> plaintext_1(::olm_decrypt_max_plaintext_length( - b_session, 0, tmp_message_1.data(), message_1.size() -)); -std::memcpy(tmp_message_1.data(), message_1.data(), message_1.size()); -assert_equals(std::size_t(12), ::olm_decrypt( - b_session, 0, - tmp_message_1.data(), message_1.size(), - plaintext_1.data(), plaintext_1.size() -)); - -for (unsigned i = 0; i < 8; ++i) { - { - std::vector<std::uint8_t> msg_a(::olm_encrypt_message_length(a_session, 12)); - std::vector<std::uint8_t> rnd_a(::olm_encrypt_random_length(a_session)); - mock_random_a(rnd_a.data(), rnd_a.size()); - std::size_t type_a = ::olm_encrypt_message_type(a_session); - assert_not_equals(std::size_t(-1), ::olm_encrypt( - a_session, plaintext, 12, rnd_a.data(), rnd_a.size(), msg_a.data(), msg_a.size() - )); - - std::vector<std::uint8_t> tmp_a(msg_a); - std::vector<std::uint8_t> out_a(::olm_decrypt_max_plaintext_length( - b_session, type_a, tmp_a.data(), tmp_a.size() - )); - std::memcpy(tmp_a.data(), msg_a.data(), sizeof(msg_a)); - assert_equals(std::size_t(12), ::olm_decrypt( - b_session, type_a, msg_a.data(), msg_a.size(), out_a.data(), out_a.size() - )); - } - { - std::vector<std::uint8_t> msg_b(::olm_encrypt_message_length(b_session, 12)); - std::vector<std::uint8_t> rnd_b(::olm_encrypt_random_length(b_session)); - mock_random_b(rnd_b.data(), rnd_b.size()); - std::size_t type_b = ::olm_encrypt_message_type(b_session); - assert_not_equals(std::size_t(-1), ::olm_encrypt( - b_session, plaintext, 12, rnd_b.data(), rnd_b.size(), msg_b.data(), msg_b.size() - )); - - std::vector<std::uint8_t> tmp_b(msg_b); - std::vector<std::uint8_t> out_b(::olm_decrypt_max_plaintext_length( - a_session, type_b, tmp_b.data(), tmp_b.size() - )); - std::memcpy(tmp_b.data(), msg_b.data(), msg_b.size()); - assert_equals(std::size_t(12), ::olm_decrypt( - a_session, type_b, msg_b.data(), msg_b.size(), out_b.data(), out_b.size() - )); - } -} -} - -} diff --git a/tests/test_olm_decrypt.cpp b/tests/test_olm_decrypt.cpp deleted file mode 100644 index 0c8feb8..0000000 --- a/tests/test_olm_decrypt.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include "olm/olm.h" -#include "unittest.hh" - -#include <vector> - -struct test_case { - const char *msghex; - const char *expected_error; -}; - -const test_case test_cases[] = { - { "41776f", "BAD_MESSAGE_FORMAT" }, - { "7fff6f0101346d671201", "BAD_MESSAGE_FORMAT" }, - { "ee776f41496f674177804177778041776f6716670a677d6f670a67c2677d", "BAD_MESSAGE_FORMAT" }, - { "e9e9c9c1e9e9c9e9c9c1e9e9c9c1", "BAD_MESSAGE_FORMAT" }, -}; - - -const char * session_data = - "E0p44KO2y2pzp9FIjv0rud2wIvWDi2dx367kP4Fz/9JCMrH+aG369HGymkFtk0+PINTLB9lQRt" - "ohea5d7G/UXQx3r5y4IWuyh1xaRnojEZQ9a5HRZSNtvmZ9NY1f1gutYa4UtcZcbvczN8b/5Bqg" - "e16cPUH1v62JKLlhoAJwRkH1wU6fbyOudERg5gdXA971btR+Q2V8GKbVbO5fGKL5phmEPVXyMs" - "rfjLdzQrgjOTxN8Pf6iuP+WFPvfnR9lDmNCFxJUVAdLIMnLuAdxf1TGcS+zzCzEE8btIZ99mHF" - "dGvPXeH8qLeNZA"; - -void decode_hex( - const char * input, - std::uint8_t * output, std::size_t output_length -) { - std::uint8_t * end = output + output_length; - while (output != end) { - char high = *(input++); - char low = *(input++); - if (high >= 'a') high -= 'a' - ('9' + 1); - if (low >= 'a') low -= 'a' - ('9' + 1); - uint8_t value = ((high - '0') << 4) | (low - '0'); - *(output++) = value; - } -} - -void decrypt_case(int message_type, const test_case * test_case) { - std::vector<std::uint8_t> session_memory(olm_session_size()); - ::OlmSession * session = ::olm_session(session_memory.data()); - - std::vector<std::uint8_t> pickled(strlen(session_data)); - ::memcpy(pickled.data(), session_data, pickled.size()); - assert_not_equals( - ::olm_error(), - ::olm_unpickle_session(session, "", 0, pickled.data(), pickled.size()) - ); - - std::size_t message_length = strlen(test_case->msghex) / 2; - std::uint8_t * message = (std::uint8_t *) ::malloc(message_length); - decode_hex(test_case->msghex, message, message_length); - - size_t max_length = olm_decrypt_max_plaintext_length( - session, message_type, message, message_length - ); - - if (test_case->expected_error) { - assert_equals(::olm_error(), max_length); - assert_equals( - std::string(test_case->expected_error), - std::string(::olm_session_last_error(session)) - ); - free(message); - return; - } - - assert_not_equals(::olm_error(), max_length); - - std::vector<uint8_t> plaintext(max_length); - decode_hex(test_case->msghex, message, message_length); - olm_decrypt( - session, message_type, - message, message_length, - plaintext.data(), max_length - ); - free(message); -} - - -int main() { -{ -TestCase my_test("Olm decrypt test"); - -for (unsigned int i = 0; i < sizeof(test_cases)/ sizeof(test_cases[0]); ++i) { - decrypt_case(0, &test_cases[i]); -} - -} -} diff --git a/tests/test_olm_sha256.cpp b/tests/test_olm_sha256.cpp deleted file mode 100644 index d76e592..0000000 --- a/tests/test_olm_sha256.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "olm/olm.h" -#include "unittest.hh" - -#include <vector> - -int main() { -{ -TestCase("Olm sha256 test"); - - -std::vector<std::uint8_t> utility_buffer(::olm_utility_size()); -::OlmUtility * utility = ::olm_utility(utility_buffer.data()); - -assert_equals(std::size_t(43), ::olm_sha256_length(utility)); -std::uint8_t output[43]; -::olm_sha256(utility, "Hello, World", 12, output, 43); - -std::uint8_t expected_output[] = "A2daxT/5zRU1zMffzfosRYxSGDcfQY3BNvLRmsH76KU"; -assert_equals(output, expected_output, 43); - -} -} diff --git a/tests/test_olm_signature.cpp b/tests/test_olm_signature.cpp deleted file mode 100644 index f53bcec..0000000 --- a/tests/test_olm_signature.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include "olm/olm.h" -#include "unittest.hh" - -#include <cstddef> -#include <cstdint> -#include <cstring> - -struct MockRandom { - MockRandom(std::uint8_t tag, std::uint8_t offset = 0) - : tag(tag), current(offset) {} - void operator()( - void * buf, std::size_t length - ) { - std::uint8_t * bytes = (std::uint8_t *) buf; - while (length > 32) { - bytes[0] = tag; - std::memset(bytes + 1, current, 31); - length -= 32; - bytes += 32; - current += 1; - } - if (length) { - bytes[0] = tag; - std::memset(bytes + 1, current, length - 1); - current += 1; - } - } - std::uint8_t tag; - std::uint8_t current; -}; - -std::uint8_t * check_malloc(std::size_t size) { - if (size == std::size_t(-1)) { - assert_not_equals(std::size_t(-1), size); - } - return (std::uint8_t *)::malloc(size); -} - - -int main() { - -{ /** Signing Test */ -TestCase test_case("Signing test"); - -MockRandom mock_random_a('A', 0x00); - -void * account_buffer = check_malloc(::olm_account_size()); -::OlmAccount * account = ::olm_account(account_buffer); - -std::size_t random_size = ::olm_create_account_random_length(account); -void * random = check_malloc(random_size); -mock_random_a(random, random_size); -::olm_create_account(account, random, random_size); -::free(random); - -std::size_t message_size = 12; -void * message = check_malloc(message_size); -::memcpy(message, "Hello, World", message_size); - -std::size_t signature_size = ::olm_account_signature_length(account); -void * signature = check_malloc(signature_size); -assert_not_equals(std::size_t(-1), ::olm_account_sign( - account, message, message_size, signature, signature_size -)); - -std::size_t id_keys_size = ::olm_account_identity_keys_length(account); -std::uint8_t * id_keys = (std::uint8_t *) check_malloc(id_keys_size); -assert_not_equals(std::size_t(-1), ::olm_account_identity_keys( - account, id_keys, id_keys_size -)); - -olm_clear_account(account); -free(account_buffer); - -void * utility_buffer = check_malloc(::olm_utility_size()); -::OlmUtility * utility = ::olm_utility(utility_buffer); - -assert_not_equals(std::size_t(-1), ::olm_ed25519_verify( - utility, id_keys + 71, 43, message, message_size, signature, signature_size -)); - -olm_clear_utility(utility); -free(utility_buffer); - -free(id_keys); -free(signature); -free(message); - -} - -} diff --git a/tests/test_olm_using_malloc.cpp b/tests/test_olm_using_malloc.cpp deleted file mode 100644 index fff3ea2..0000000 --- a/tests/test_olm_using_malloc.cpp +++ /dev/null @@ -1,210 +0,0 @@ -#include "olm/olm.h" -#include "unittest.hh" - -#include <cstddef> -#include <cstdint> -#include <cstring> - -struct MockRandom { - MockRandom(std::uint8_t tag, std::uint8_t offset = 0) - : tag(tag), current(offset) {} - void operator()( - void * buf, std::size_t length - ) { - std::uint8_t * bytes = (std::uint8_t *) buf; - while (length > 32) { - bytes[0] = tag; - std::memset(bytes + 1, current, 31); - length -= 32; - bytes += 32; - current += 1; - } - if (length) { - bytes[0] = tag; - std::memset(bytes + 1, current, length - 1); - current += 1; - } - } - std::uint8_t tag; - std::uint8_t current; -}; - -std::uint8_t * check_malloc(std::size_t size) { - if (size == std::size_t(-1)) { - assert_not_equals(std::size_t(-1), size); - } - return (std::uint8_t *)::malloc(size); -} - -int main() { - -{ /** More messages test */ - -TestCase test_case("More messages test"); -MockRandom mock_random_a('A', 0x00); -MockRandom mock_random_b('B', 0x80); - -void * a_account_buffer = check_malloc(::olm_account_size()); -::OlmAccount *a_account = ::olm_account(a_account_buffer); - -std::size_t a_random_size = ::olm_create_account_random_length(a_account); -void * a_random = check_malloc(a_random_size); -mock_random_a(a_random, a_random_size); -::olm_create_account(a_account, a_random, a_random_size); -free(a_random); - -void * b_account_buffer = check_malloc(::olm_account_size()); -::OlmAccount *b_account = ::olm_account(b_account_buffer); - -std::size_t b_random_size = ::olm_create_account_random_length(b_account); -void * b_random = check_malloc(b_random_size); -mock_random_b(b_random, b_random_size); -::olm_create_account(b_account, b_random, b_random_size); -free(b_random); - -std::size_t o_random_size = ::olm_account_generate_one_time_keys_random_length( - b_account, 42 -); -void * o_random = check_malloc(o_random_size); -mock_random_b(o_random, o_random_size); -::olm_account_generate_one_time_keys(b_account, 42, o_random, o_random_size); -free(o_random); - - -std::size_t b_id_keys_size = ::olm_account_identity_keys_length(b_account); -std::size_t b_ot_keys_size = ::olm_account_one_time_keys_length(b_account); -std::uint8_t * b_id_keys = (std::uint8_t *) check_malloc(b_id_keys_size); -std::uint8_t * b_ot_keys = (std::uint8_t *) check_malloc(b_ot_keys_size); -::olm_account_identity_keys(b_account, b_id_keys, b_id_keys_size); -::olm_account_one_time_keys(b_account, b_ot_keys, b_ot_keys_size); - -void * a_session_buffer = check_malloc(::olm_session_size()); -::OlmSession *a_session = ::olm_session(a_session_buffer); - -std::size_t a_rand_size = ::olm_create_outbound_session_random_length(a_session); -void * a_rand = check_malloc(a_rand_size); -mock_random_a(a_rand, a_rand_size); -assert_not_equals(std::size_t(-1), ::olm_create_outbound_session( - a_session, a_account, - b_id_keys + 15, 43, - b_ot_keys + 25, 43, - a_rand, a_rand_size -)); -free(b_id_keys); -free(b_ot_keys); -free(a_rand); - -void * plaintext = malloc(12); -::memcpy(plaintext, "Hello, World", 12); - -std::size_t message_1_size = ::olm_encrypt_message_length(a_session, 12); -void * message_1 = check_malloc(message_1_size); -std::size_t a_message_random_size = ::olm_encrypt_random_length(a_session); -void * a_message_random = check_malloc(a_message_random_size); -mock_random_a(a_message_random, a_message_random_size); -assert_equals(std::size_t(0), ::olm_encrypt_message_type(a_session)); -assert_not_equals(std::size_t(-1), ::olm_encrypt( - a_session, - plaintext, 12, - a_message_random, a_message_random_size, - message_1, message_1_size -)); -free(a_message_random); - -void * tmp_message_1 = check_malloc(message_1_size); -std::memcpy(tmp_message_1, message_1, message_1_size); - -void * b_session_buffer = check_malloc(olm_account_size()); -::OlmSession *b_session = ::olm_session(b_session_buffer); -::olm_create_inbound_session( - b_session, b_account, tmp_message_1, message_1_size -); - -std::memcpy(tmp_message_1, message_1, message_1_size); - -std::size_t plaintext_1_size = ::olm_decrypt_max_plaintext_length( - b_session, 0, tmp_message_1, message_1_size -); -void * plaintext_1 = check_malloc(plaintext_1_size); -std::memcpy(tmp_message_1, message_1, message_1_size); -assert_equals(std::size_t(12), ::olm_decrypt( - b_session, 0, - tmp_message_1, message_1_size, - plaintext_1, plaintext_1_size -)); -free(tmp_message_1); -free(plaintext_1); -free(message_1); - -assert_not_equals( - std::size_t(-1), ::olm_remove_one_time_keys(b_account, b_session) -); - -for (unsigned i = 0; i < 8; ++i) { - { - std::size_t msg_a_size = ::olm_encrypt_message_length(a_session, 12); - std::size_t rnd_a_size = ::olm_encrypt_random_length(a_session); - void * msg_a = check_malloc(msg_a_size); - void * rnd_a = check_malloc(rnd_a_size); - mock_random_a(rnd_a, rnd_a_size); - std::size_t type_a = ::olm_encrypt_message_type(a_session); - assert_not_equals(std::size_t(-1), ::olm_encrypt( - a_session, plaintext, 12, rnd_a, rnd_a_size, msg_a, msg_a_size - )); - free(rnd_a); - - void * tmp_a = check_malloc(msg_a_size); - std::memcpy(tmp_a, msg_a, msg_a_size); - std::size_t out_a_size = ::olm_decrypt_max_plaintext_length( - b_session, type_a, tmp_a, msg_a_size - ); - void * out_a = check_malloc(out_a_size); - std::memcpy(tmp_a, msg_a, msg_a_size); - assert_equals(std::size_t(12), ::olm_decrypt( - b_session, type_a, tmp_a, msg_a_size, out_a, out_a_size - )); - free(tmp_a); - free(msg_a); - free(out_a); - } - { - std::size_t msg_b_size = ::olm_encrypt_message_length(b_session, 12); - std::size_t rnd_b_size = ::olm_encrypt_random_length(b_session); - void * msg_b = check_malloc(msg_b_size); - void * rnd_b = check_malloc(rnd_b_size); - mock_random_b(rnd_b, rnd_b_size); - std::size_t type_b = ::olm_encrypt_message_type(b_session); - assert_not_equals(std::size_t(-1), ::olm_encrypt( - b_session, plaintext, 12, rnd_b, rnd_b_size, msg_b, msg_b_size - )); - free(rnd_b); - - void * tmp_b = check_malloc(msg_b_size); - std::memcpy(tmp_b, msg_b, msg_b_size); - std::size_t out_b_size = ::olm_decrypt_max_plaintext_length( - a_session, type_b, tmp_b, msg_b_size - ); - void * out_b = check_malloc(out_b_size); - std::memcpy(tmp_b, msg_b, msg_b_size); - assert_equals(std::size_t(12), ::olm_decrypt( - a_session, type_b, msg_b, msg_b_size, out_b, out_b_size - )); - free(tmp_b); - free(msg_b); - free(out_b); - } -} -::olm_clear_account(a_account); -::olm_clear_account(b_account); -::olm_clear_session(a_session); -::olm_clear_session(b_session); - -free(a_account_buffer); -free(b_account_buffer); -free(a_session_buffer); -free(b_session_buffer); -free(plaintext); - -} - -} diff --git a/tests/test_pk.cpp b/tests/test_pk.cpp deleted file mode 100644 index b917a2e..0000000 --- a/tests/test_pk.cpp +++ /dev/null @@ -1,236 +0,0 @@ -#include "olm/pk.h" -#include "olm/crypto.h" -#include "olm/olm.h" - -#include "unittest.hh" - -#include <iostream> -#include <vector> - -int main() { - - -{ /* Encryption Test Case 1 */ - -TestCase test_case("Public Key Encryption/Decryption Test Case 1"); - -std::vector<std::uint8_t> decryption_buffer(olm_pk_decryption_size()); -OlmPkDecryption *decryption = olm_pk_decryption(decryption_buffer.data()); - -std::uint8_t alice_private[32] = { - 0x77, 0x07, 0x6D, 0x0A, 0x73, 0x18, 0xA5, 0x7D, - 0x3C, 0x16, 0xC1, 0x72, 0x51, 0xB2, 0x66, 0x45, - 0xDF, 0x4C, 0x2F, 0x87, 0xEB, 0xC0, 0x99, 0x2A, - 0xB1, 0x77, 0xFB, 0xA5, 0x1D, 0xB9, 0x2C, 0x2A -}; - -const std::uint8_t *alice_public = (std::uint8_t *) "hSDwCYkwp1R0i33ctD73Wg2/Og0mOBr066SpjqqbTmo"; - -std::uint8_t bob_private[32] = { - 0x5D, 0xAB, 0x08, 0x7E, 0x62, 0x4A, 0x8A, 0x4B, - 0x79, 0xE1, 0x7F, 0x8B, 0x83, 0x80, 0x0E, 0xE6, - 0x6F, 0x3B, 0xB1, 0x29, 0x26, 0x18, 0xB6, 0xFD, - 0x1C, 0x2F, 0x8B, 0x27, 0xFF, 0x88, 0xE0, 0xEB -}; - -const std::uint8_t *bob_public = (std::uint8_t *) "3p7bfXt9wbTTW2HC7OQ1Nz+DQ8hbeGdNrfx+FG+IK08"; - -std::vector<std::uint8_t> pubkey(::olm_pk_key_length()); - -olm_pk_key_from_private( - decryption, - pubkey.data(), pubkey.size(), - alice_private, sizeof(alice_private) -); - -assert_equals(alice_public, pubkey.data(), olm_pk_key_length()); - -uint8_t *alice_private_back_out = (uint8_t *)malloc(olm_pk_private_key_length()); -olm_pk_get_private_key(decryption, alice_private_back_out, olm_pk_private_key_length()); -assert_equals(alice_private, alice_private_back_out, olm_pk_private_key_length()); -free(alice_private_back_out); - -std::vector<std::uint8_t> encryption_buffer(olm_pk_encryption_size()); -OlmPkEncryption *encryption = olm_pk_encryption(encryption_buffer.data()); - -olm_pk_encryption_set_recipient_key(encryption, pubkey.data(), pubkey.size()); - -const size_t plaintext_length = 14; -const std::uint8_t *plaintext = (std::uint8_t *) "This is a test"; - -size_t ciphertext_length = olm_pk_ciphertext_length(encryption, plaintext_length); -std::uint8_t *ciphertext_buffer = (std::uint8_t *) malloc(ciphertext_length); - -std::vector<std::uint8_t> output_buffer(olm_pk_mac_length(encryption)); -std::vector<std::uint8_t> ephemeral_key(olm_pk_key_length()); - -olm_pk_encrypt( - encryption, - plaintext, plaintext_length, - ciphertext_buffer, ciphertext_length, - output_buffer.data(), output_buffer.size(), - ephemeral_key.data(), ephemeral_key.size(), - bob_private, sizeof(bob_private) -); - -assert_equals(bob_public, ephemeral_key.data(), olm_pk_key_length()); - -size_t max_plaintext_length = olm_pk_max_plaintext_length(decryption, ciphertext_length); -std::uint8_t *plaintext_buffer = (std::uint8_t *) malloc(max_plaintext_length); - -olm_pk_decrypt( - decryption, - ephemeral_key.data(), ephemeral_key.size(), - output_buffer.data(), output_buffer.size(), - ciphertext_buffer, ciphertext_length, - plaintext_buffer, max_plaintext_length -); - -assert_equals(plaintext, plaintext_buffer, plaintext_length); - -free(ciphertext_buffer); -free(plaintext_buffer); - -} - -{ /* Encryption Test Case 1 */ - -TestCase test_case("Public Key Decryption pickling"); - -std::vector<std::uint8_t> decryption_buffer(olm_pk_decryption_size()); -OlmPkDecryption *decryption = olm_pk_decryption(decryption_buffer.data()); - -std::uint8_t alice_private[32] = { - 0x77, 0x07, 0x6D, 0x0A, 0x73, 0x18, 0xA5, 0x7D, - 0x3C, 0x16, 0xC1, 0x72, 0x51, 0xB2, 0x66, 0x45, - 0xDF, 0x4C, 0x2F, 0x87, 0xEB, 0xC0, 0x99, 0x2A, - 0xB1, 0x77, 0xFB, 0xA5, 0x1D, 0xB9, 0x2C, 0x2A -}; - -const std::uint8_t *alice_public = (std::uint8_t *) "hSDwCYkwp1R0i33ctD73Wg2/Og0mOBr066SpjqqbTmoK"; - -std::vector<std::uint8_t> pubkey(olm_pk_key_length()); - -olm_pk_key_from_private( - decryption, - pubkey.data(), pubkey.size(), - alice_private, sizeof(alice_private) -); - -const uint8_t *PICKLE_KEY=(uint8_t *)"secret_key"; -std::vector<std::uint8_t> pickle_buffer(olm_pickle_pk_decryption_length(decryption)); -const uint8_t *expected_pickle = (uint8_t *) "qx37WTQrjZLz5tId/uBX9B3/okqAbV1ofl9UnHKno1eipByCpXleAAlAZoJgYnCDOQZDQWzo3luTSfkF9pU1mOILCbbouubs6TVeDyPfgGD9i86J8irHjA"; - -olm_pickle_pk_decryption( - decryption, - PICKLE_KEY, strlen((char *)PICKLE_KEY), - pickle_buffer.data(), pickle_buffer.size() -); -assert_equals(expected_pickle, pickle_buffer.data(), olm_pickle_pk_decryption_length(decryption)); - -olm_clear_pk_decryption(decryption); - -memset(pubkey.data(), 0, olm_pk_key_length()); - -olm_unpickle_pk_decryption( - decryption, - PICKLE_KEY, strlen((char *)PICKLE_KEY), - pickle_buffer.data(), pickle_buffer.size(), - pubkey.data(), pubkey.size() -); - -assert_equals(alice_public, pubkey.data(), olm_pk_key_length()); - -char *ciphertext = strdup("ntk49j/KozVFtSqJXhCejg"); -const char *mac = "zpzU6BkZcNI"; -const char *ephemeral_key = "3p7bfXt9wbTTW2HC7OQ1Nz+DQ8hbeGdNrfx+FG+IK08"; - -size_t max_plaintext_length = olm_pk_max_plaintext_length(decryption, strlen(ciphertext)); -std::uint8_t *plaintext_buffer = (std::uint8_t *) malloc(max_plaintext_length); - -olm_pk_decrypt( - decryption, - ephemeral_key, strlen(ephemeral_key), - mac, strlen(mac), - ciphertext, strlen(ciphertext), - plaintext_buffer, max_plaintext_length -); - -const std::uint8_t *plaintext = (std::uint8_t *) "This is a test"; - -assert_equals(plaintext, plaintext_buffer, strlen((const char *)plaintext)); - -free(ciphertext); -free(plaintext_buffer); - -} - -{ /* Signing Test Case 1 */ - -TestCase test_case("Public Key Signing"); - -std::vector<std::uint8_t> signing_buffer(olm_pk_signing_size()); -OlmPkSigning *signing = olm_pk_signing(signing_buffer.data()); - -std::uint8_t seed[32] = { - 0x77, 0x07, 0x6D, 0x0A, 0x73, 0x18, 0xA5, 0x7D, - 0x3C, 0x16, 0xC1, 0x72, 0x51, 0xB2, 0x66, 0x45, - 0xDF, 0x4C, 0x2F, 0x87, 0xEB, 0xC0, 0x99, 0x2A, - 0xB1, 0x77, 0xFB, 0xA5, 0x1D, 0xB9, 0x2C, 0x2A -}; - -//const std::uint8_t *pub_key = (std::uint8_t *) "hSDwCYkwp1R0i33ctD73Wg2/Og0mOBr066SpjqqbTmoK"; - -std::vector<char> pubkey(olm_pk_signing_public_key_length() + 1); - -olm_pk_signing_key_from_seed( - signing, - pubkey.data(), pubkey.size() - 1, - seed, sizeof(seed) -); - -char *message = strdup("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."); - -std::uint8_t *sig_buffer = (std::uint8_t *) malloc(olm_pk_signature_length() + 1); - -olm_pk_sign( - signing, - (const uint8_t *)message, strlen(message), - sig_buffer, olm_pk_signature_length() -); - -void * utility_buffer = malloc(::olm_utility_size()); -::OlmUtility * utility = ::olm_utility(utility_buffer); - -size_t result; - -result = ::olm_ed25519_verify( - utility, - pubkey.data(), olm_pk_signing_public_key_length(), - message, strlen(message), - sig_buffer, olm_pk_signature_length() -); - -assert_equals((size_t)0, result); - -sig_buffer[5] = 'm'; - -result = ::olm_ed25519_verify( - utility, - pubkey.data(), olm_pk_signing_public_key_length(), - message, strlen(message), - sig_buffer, olm_pk_signature_length() -); - -assert_equals((size_t)-1, result); - -olm_clear_utility(utility); -free(utility_buffer); - -free(message); -free(sig_buffer); - -olm_clear_pk_signing(signing); - -} -} diff --git a/tests/test_ratchet.cpp b/tests/test_ratchet.cpp deleted file mode 100644 index 0408429..0000000 --- a/tests/test_ratchet.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/* Copyright 2015 OpenMarket Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "olm/ratchet.hh" -#include "olm/cipher.h" -#include "unittest.hh" - -#include <vector> - -int main() { - -std::uint8_t root_info[] = "Olm"; -std::uint8_t ratchet_info[] = "OlmRatchet"; -std::uint8_t message_info[] = "OlmMessageKeys"; - -olm::KdfInfo kdf_info = { - root_info, sizeof(root_info) - 1, - ratchet_info, sizeof(ratchet_info) - 1 -}; - -_olm_cipher_aes_sha_256 cipher0 = OLM_CIPHER_INIT_AES_SHA_256(message_info); -_olm_cipher *cipher = OLM_CIPHER_BASE(&cipher0); - -std::uint8_t random_bytes[] = "0123456789ABDEF0123456789ABCDEF"; -_olm_curve25519_key_pair alice_key; -_olm_crypto_curve25519_generate_key(random_bytes, &alice_key); - -std::uint8_t shared_secret[] = "A secret"; - -{ /* Send/Receive test case */ -TestCase test_case("Olm Send/Receive"); - -olm::Ratchet alice(kdf_info, cipher); -olm::Ratchet bob(kdf_info, cipher); - -alice.initialise_as_alice(shared_secret, sizeof(shared_secret) - 1, alice_key); -bob.initialise_as_bob(shared_secret, sizeof(shared_secret) - 1, alice_key.public_key); - -std::uint8_t plaintext[] = "Message"; -std::size_t plaintext_length = sizeof(plaintext) - 1; - -std::size_t message_length, random_length, output_length; -std::size_t encrypt_length, decrypt_length; -{ - /* Alice sends Bob a message */ - message_length = alice.encrypt_output_length(plaintext_length); - random_length = alice.encrypt_random_length(); - assert_equals(std::size_t(0), random_length); - - std::vector<std::uint8_t> message(message_length); - - encrypt_length = alice.encrypt( - plaintext, plaintext_length, - NULL, 0, - message.data(), message_length - ); - assert_equals(message_length, encrypt_length); - - output_length = bob.decrypt_max_plaintext_length(message.data(), message_length); - std::vector<std::uint8_t> output(output_length); - decrypt_length = bob.decrypt( - message.data(), message_length, - output.data(), output_length - ); - assert_equals(plaintext_length, decrypt_length); - assert_equals(plaintext, output.data(), decrypt_length); -} - - -{ - /* Bob sends Alice a message */ - message_length = bob.encrypt_output_length(plaintext_length); - random_length = bob.encrypt_random_length(); - assert_equals(std::size_t(32), random_length); - - std::vector<std::uint8_t> message(message_length); - std::uint8_t random[] = "This is a random 32 byte string."; - - encrypt_length = bob.encrypt( - plaintext, plaintext_length, - random, 32, - message.data(), message_length - ); - assert_equals(message_length, encrypt_length); - - output_length = alice.decrypt_max_plaintext_length(message.data(), message_length); - std::vector<std::uint8_t> output(output_length); - decrypt_length = alice.decrypt( - message.data(), message_length, - output.data(), output_length - ); - assert_equals(plaintext_length, decrypt_length); - assert_equals(plaintext, output.data(), decrypt_length); -} - -} /* Send/receive message test case */ - -{ /* Out of order test case */ - -TestCase test_case("Olm Out of Order"); - -olm::Ratchet alice(kdf_info, cipher); -olm::Ratchet bob(kdf_info, cipher); - -alice.initialise_as_alice(shared_secret, sizeof(shared_secret) - 1, alice_key); -bob.initialise_as_bob(shared_secret, sizeof(shared_secret) - 1, alice_key.public_key); - -std::uint8_t plaintext_1[] = "First Message"; -std::size_t plaintext_1_length = sizeof(plaintext_1) - 1; - -std::uint8_t plaintext_2[] = "Second Messsage. A bit longer than the first."; -std::size_t plaintext_2_length = sizeof(plaintext_2) - 1; - -std::size_t message_1_length, message_2_length, random_length, output_length; -std::size_t encrypt_length, decrypt_length; - -{ - /* Alice sends Bob two messages and they arrive out of order */ - message_1_length = alice.encrypt_output_length(plaintext_1_length); - random_length = alice.encrypt_random_length(); - assert_equals(std::size_t(0), random_length); - - std::vector<std::uint8_t> message_1(message_1_length); - std::uint8_t random[] = "This is a random 32 byte string."; - encrypt_length = alice.encrypt( - plaintext_1, plaintext_1_length, - random, 32, - message_1.data(), message_1_length - ); - assert_equals(message_1_length, encrypt_length); - - message_2_length = alice.encrypt_output_length(plaintext_2_length); - random_length = alice.encrypt_random_length(); - assert_equals(std::size_t(0), random_length); - - std::vector<std::uint8_t> message_2(message_2_length); - encrypt_length = alice.encrypt( - plaintext_2, plaintext_2_length, - NULL, 0, - message_2.data(), message_2_length - ); - assert_equals(message_2_length, encrypt_length); - - output_length = bob.decrypt_max_plaintext_length( - message_2.data(), message_2_length - ); - std::vector<std::uint8_t> output_1(output_length); - decrypt_length = bob.decrypt( - message_2.data(), message_2_length, - output_1.data(), output_length - ); - assert_equals(plaintext_2_length, decrypt_length); - assert_equals(plaintext_2, output_1.data(), decrypt_length); - - output_length = bob.decrypt_max_plaintext_length( - message_1.data(), message_1_length - ); - std::vector<std::uint8_t> output_2(output_length); - decrypt_length = bob.decrypt( - message_1.data(), message_1_length, - output_2.data(), output_length - ); - - assert_equals(plaintext_1_length, decrypt_length); - assert_equals(plaintext_1, output_2.data(), decrypt_length); -} - -} /* Out of order test case */ - -{ /* More messages */ - -TestCase test_case("Olm More Messages"); - -olm::Ratchet alice(kdf_info, cipher); -olm::Ratchet bob(kdf_info, cipher); - -alice.initialise_as_alice(shared_secret, sizeof(shared_secret) - 1, alice_key); -bob.initialise_as_bob(shared_secret, sizeof(shared_secret) - 1, alice_key.public_key); - -std::uint8_t plaintext[] = "These 15 bytes"; -assert_equals(std::size_t(15), sizeof(plaintext)); -std::uint8_t random[] = "This is a random 32 byte string"; - -for (unsigned i = 0; i < 8; ++i) { -{ - std::vector<std::uint8_t> msg(alice.encrypt_output_length(sizeof(plaintext))); - alice.encrypt( - plaintext, 15, random, 32, msg.data(), msg.size() - ); - std::vector<std::uint8_t> output(bob.decrypt_max_plaintext_length(msg.data(), msg.size())); - assert_equals( - std::size_t(15), bob.decrypt(msg.data(), msg.size(), output.data(), output.size()) - ); -} -random[31]++; -{ - std::vector<std::uint8_t> msg(bob.encrypt_output_length(sizeof(plaintext))); - bob.encrypt( - plaintext, 15, random, 32, msg.data(), msg.size() - ); - std::vector<std::uint8_t> output(alice.decrypt_max_plaintext_length(msg.data(), msg.size())); - assert_equals( - std::size_t(15), alice.decrypt(msg.data(), msg.size(), output.data(), output.size()) - ); -} -random[31]++; -} - -} - -} diff --git a/tests/test_sas.cpp b/tests/test_sas.cpp deleted file mode 100644 index 48b9ee6..0000000 --- a/tests/test_sas.cpp +++ /dev/null @@ -1,118 +0,0 @@ -#include "olm/sas.h" -#include "olm/crypto.h" -#include "olm/olm.h" - -#include "unittest.hh" - -#include <iostream> -#include <vector> - -int main() { - - -{ /* Generate bytes */ - -TestCase test_case("SAS generate bytes"); - -std::uint8_t alice_private[32] = { - 0x77, 0x07, 0x6D, 0x0A, 0x73, 0x18, 0xA5, 0x7D, - 0x3C, 0x16, 0xC1, 0x72, 0x51, 0xB2, 0x66, 0x45, - 0xDF, 0x4C, 0x2F, 0x87, 0xEB, 0xC0, 0x99, 0x2A, - 0xB1, 0x77, 0xFB, 0xA5, 0x1D, 0xB9, 0x2C, 0x2A -}; - -const std::uint8_t *alice_public = (std::uint8_t *) "hSDwCYkwp1R0i33ctD73Wg2/Og0mOBr066SpjqqbTmo"; - -std::uint8_t bob_private[32] = { - 0x5D, 0xAB, 0x08, 0x7E, 0x62, 0x4A, 0x8A, 0x4B, - 0x79, 0xE1, 0x7F, 0x8B, 0x83, 0x80, 0x0E, 0xE6, - 0x6F, 0x3B, 0xB1, 0x29, 0x26, 0x18, 0xB6, 0xFD, - 0x1C, 0x2F, 0x8B, 0x27, 0xFF, 0x88, 0xE0, 0xEB -}; - -const std::uint8_t *bob_public = (std::uint8_t *) "3p7bfXt9wbTTW2HC7OQ1Nz+DQ8hbeGdNrfx+FG+IK08"; - -std::vector<std::uint8_t> alice_sas_buffer(olm_sas_size()); -OlmSAS *alice_sas = olm_sas(alice_sas_buffer.data()); -olm_create_sas(alice_sas, alice_private, sizeof(alice_private)); -std::vector<std::uint8_t> bob_sas_buffer(olm_sas_size()); -OlmSAS *bob_sas = olm_sas(bob_sas_buffer.data()); -olm_create_sas(bob_sas, bob_private, sizeof(bob_private)); - -std::vector<std::uint8_t> pubkey(::olm_sas_pubkey_length(alice_sas)); - -olm_sas_get_pubkey(alice_sas, pubkey.data(), pubkey.size()); - -assert_equals(alice_public, pubkey.data(), olm_sas_pubkey_length(alice_sas)); - -olm_sas_set_their_key(bob_sas, pubkey.data(), olm_sas_pubkey_length(bob_sas)); - -olm_sas_get_pubkey(bob_sas, pubkey.data(), pubkey.size()); - -assert_equals(bob_public, pubkey.data(), olm_sas_pubkey_length(bob_sas)); - -olm_sas_set_their_key(alice_sas, pubkey.data(), olm_sas_pubkey_length(alice_sas)); - -std::uint8_t alice_bytes[6]; -std::uint8_t bob_bytes[6]; - -olm_sas_generate_bytes(alice_sas, "SAS", 3, alice_bytes, 6); -olm_sas_generate_bytes(bob_sas, "SAS", 3, bob_bytes, 6); - -assert_equals(alice_bytes, bob_bytes, 6); - -} - -{ /* Calculate MAC */ - -TestCase test_case("SAS calculate MAC"); - -std::uint8_t alice_private[32] = { - 0x77, 0x07, 0x6D, 0x0A, 0x73, 0x18, 0xA5, 0x7D, - 0x3C, 0x16, 0xC1, 0x72, 0x51, 0xB2, 0x66, 0x45, - 0xDF, 0x4C, 0x2F, 0x87, 0xEB, 0xC0, 0x99, 0x2A, - 0xB1, 0x77, 0xFB, 0xA5, 0x1D, 0xB9, 0x2C, 0x2A -}; - -const std::uint8_t *alice_public = (std::uint8_t *) "hSDwCYkwp1R0i33ctD73Wg2/Og0mOBr066SpjqqbTmo"; - -std::uint8_t bob_private[32] = { - 0x5D, 0xAB, 0x08, 0x7E, 0x62, 0x4A, 0x8A, 0x4B, - 0x79, 0xE1, 0x7F, 0x8B, 0x83, 0x80, 0x0E, 0xE6, - 0x6F, 0x3B, 0xB1, 0x29, 0x26, 0x18, 0xB6, 0xFD, - 0x1C, 0x2F, 0x8B, 0x27, 0xFF, 0x88, 0xE0, 0xEB -}; - -const std::uint8_t *bob_public = (std::uint8_t *) "3p7bfXt9wbTTW2HC7OQ1Nz+DQ8hbeGdNrfx+FG+IK08"; - -std::vector<std::uint8_t> alice_sas_buffer(olm_sas_size()); -OlmSAS *alice_sas = olm_sas(alice_sas_buffer.data()); -olm_create_sas(alice_sas, alice_private, sizeof(alice_private)); -std::vector<std::uint8_t> bob_sas_buffer(olm_sas_size()); -OlmSAS *bob_sas = olm_sas(bob_sas_buffer.data()); -olm_create_sas(bob_sas, bob_private, sizeof(bob_private)); - -std::vector<std::uint8_t> pubkey(::olm_sas_pubkey_length(alice_sas)); - -olm_sas_get_pubkey(alice_sas, pubkey.data(), pubkey.size()); - -assert_equals(alice_public, pubkey.data(), olm_sas_pubkey_length(alice_sas)); - -olm_sas_set_their_key(bob_sas, pubkey.data(), olm_sas_pubkey_length(bob_sas)); - -olm_sas_get_pubkey(bob_sas, pubkey.data(), pubkey.size()); - -assert_equals(bob_public, pubkey.data(), olm_sas_pubkey_length(bob_sas)); - -olm_sas_set_their_key(alice_sas, pubkey.data(), olm_sas_pubkey_length(alice_sas)); - -std::vector<std::uint8_t> alice_mac(olm_sas_mac_length(alice_sas)); -std::vector<std::uint8_t> bob_mac(olm_sas_mac_length(bob_sas)); - -olm_sas_calculate_mac(alice_sas, (void *) "Hello world!", 12, "MAC", 3, alice_mac.data(), olm_sas_mac_length(alice_sas)); -olm_sas_calculate_mac(bob_sas, (void *) "Hello world!", 12, "MAC", 3, bob_mac.data(), olm_sas_mac_length(bob_sas)); - -assert_equals(alice_mac.data(), bob_mac.data(), olm_sas_mac_length(alice_sas)); - -} -} diff --git a/tests/test_session.cpp b/tests/test_session.cpp deleted file mode 100644 index e2c3199..0000000 --- a/tests/test_session.cpp +++ /dev/null @@ -1,144 +0,0 @@ -#include "olm/session.hh" -#include "olm/pickle_encoding.h" - -#include "unittest.hh" - -/* decode into a buffer, which is returned */ -std::uint8_t *decode_hex( - const char * input -) { - static std::uint8_t buf[256]; - std::uint8_t *p = buf; - while (*input != '\0') { - char high = *(input++); - char low = *(input++); - if (high >= 'a') high -= 'a' - ('9' + 1); - if (low >= 'a') low -= 'a' - ('9' + 1); - uint8_t value = ((high - '0') << 4) | (low - '0'); - *p++ = value; - } - return buf; -} - -void check_session(const olm::Session &session) { - assert_equals( - decode_hex("49d640dc96b80176694af69fc4b8ca9fac49aecbd697d01fd8bee1ed2693b6c9"), - session.ratchet.root_key, 32 - ); - - assert_equals( - std::size_t(1), - session.ratchet.sender_chain.size() - ); - - assert_equals( - decode_hex("f77a03eaa9b301fa7d2a5aa6b50286906de12cc96044f526dbbcb12839ad7003"), - session.ratchet.sender_chain[0].ratchet_key.public_key.public_key, 32 - ); - - assert_equals( - decode_hex("d945c6ed4c7c277117adf11fb133a7936d287afe97c0b3ac989644b4490d4f31"), - session.ratchet.sender_chain[0].ratchet_key.private_key.private_key, 32 - ); - - assert_equals( - std::uint32_t(0), - session.ratchet.sender_chain[0].chain_key.index - ); - - assert_equals( - std::size_t(0), - session.ratchet.receiver_chains.size() - ); - - assert_equals( - std::size_t(0), - session.ratchet.skipped_message_keys.size() - ); - - assert_equals(OLM_SUCCESS, session.last_error); - assert_equals(false, session.received_message); - - assert_equals( - decode_hex("7326b58623a3f7bd8da11a1bab51f432c02a7430241b326e9fc8916a21eb257e"), - session.alice_identity_key.public_key, 32 - ); - - assert_equals( - decode_hex("0ab4b30bde20bd374ceccc72861660f0fd046f7516900796c3e5de41c598316c"), - session.alice_base_key.public_key, 32 - ); - - assert_equals( - decode_hex("585dba930b10d90d81702c715f4085d07c42b0cd2d676010bb6086c86c4cc618"), - session.bob_one_time_key.public_key, 32 - ); -} - -int main() { - -{ - TestCase test_case("V1 session pickle"); - - const uint8_t *PICKLE_KEY=(uint8_t *)"secret_key"; - uint8_t pickled[] = - "wkEpwMgiAqD7B1/Lw2cKYYDcUZVOd9QHes7ZroWxr/Rp/nWEAySgRsIu/a54YhO67rwitr" - "Lpos7tFxxK9IZ7pKB1qrR1coVWIt78V9lp9WgmBAvxHBSY+tu1lkL/JjLi963/yFdPancZ" - "+WHMVfaKlV3gWGpo7EfNK6qAOxI1Ea/eCsE2sYrsHEDvLLGlKAA9E56rmmoe2w6TKzsQjs" - "ZM2/XT2eJ82EgMO9pL02iLElXWmGNv72Ut7DouR0pQIT50HIEEKcFxYcoTb3WCfJD76Coe" - "sE4kx+TA6d45Xu1bwQNNkTGF+nCCu/GmKY+sECXbz9U6WhxG0YdF9Z4T8YkWYAgpKNS0FW" - "RV"; - size_t pickle_len = _olm_enc_input( - PICKLE_KEY, strlen((char *)PICKLE_KEY), - pickled, strlen((char *)pickled), NULL - ); - - olm::Session session; - const uint8_t *unpickle_res = olm::unpickle(pickled, pickled+sizeof(pickled), session); - assert_equals( - pickle_len, (size_t)(unpickle_res - pickled) - ); - - check_session(session); - -#if 0 - size_t rawlen = olm::pickle_length(session); - uint8_t *r1 = _olm_enc_output_pos(pickled, rawlen); - olm::pickle(r1, session); - _olm_enc_output( - PICKLE_KEY, strlen((char *)PICKLE_KEY), - pickled, rawlen); - printf("%s\n", pickled); -#endif -} - -{ - TestCase test_case("V2 session pickle"); - - const uint8_t *PICKLE_KEY=(uint8_t *)"secret_key"; - uint8_t pickled[] = - "m+DS/q34MXpw2xp50ZD0B7val1mlMpQXo0mx+VPje0weFYRRuuZQBdJgcFPEpi2MVSpA4c" - "qgqHyj2/bU7/lz+BXkEBrCFVx0BJidxXfOLDW4TNtRhLS1YHJNGP8GvTg1+dCytBTLsCdm" - "5f945Eq1U/pY3Cg96YTUufFP6EYrfRoDbAsRHc+h+wKKftQv+W44yUmRhcCemGHtpxk3UQ" - "AMCI7EBv9BvveyZMy3p9qZ3xvFK34Hef+R7gjtFycz7Nk/4UF46sT3cTmUlXz9iFW4uz2F" - "rTI1Wjym+l0DadsbSpHSUjmp9zt4qRP2UjwfZ5QNLv+cdObIfqFsiThGu/PlKigdF4SLHr" - "nG"; - - size_t pickle_len = _olm_enc_input( - PICKLE_KEY, strlen((char *)PICKLE_KEY), - pickled, strlen((char *)pickled), NULL - ); - - olm::Session session; - const uint8_t *unpickle_res = olm::unpickle(pickled, pickled+sizeof(pickled), session); - assert_equals( - pickle_len, (size_t)(unpickle_res - pickled) - ); - - check_session(session); -} - - - -return 0; -} diff --git a/tracing/README.rst b/tracing/README.rst deleted file mode 100644 index d2846ef..0000000 --- a/tracing/README.rst +++ /dev/null @@ -1,8 +0,0 @@ -Tracing -======= - -To see what crypto functions are being called with what input run - -.. code:: bash - - gdb --batch -x tracing/trace.gdb ./build/test_ratchet | grep "^[- ]" | tr "{}" "[]" | tracing/graph.py diff --git a/tracing/graph.py b/tracing/graph.py deleted file mode 100755 index aa51b6a..0000000 --- a/tracing/graph.py +++ /dev/null @@ -1,100 +0,0 @@ -#! /usr/bin/env python - -import sys -import yaml -import array - -class Call(object): - def __init__(self, call): - self.func, = call - args = dict(call[self.func]) - self.output = array.array("B", args.pop("output")).tostring() - self.inputs = { - name: array.array("B", args[name]).tostring() - for name in args - if not name.endswith("_length") - } - self.bind = {} - - def expr(self, stream, indent=" ", level=""): - stream.write(self.func + "(\n") - for name, value in self.inputs.items(): - stream.write(level + indent + name + "=") - self.bind.get(name, Literal(value)).expr( - stream, indent, level + indent - ) - stream.write(",\n") - stream.write(level + ")") - - -class Literal(str): - def expr(self, stream, indent, level): - stream.write("\"" + self.encode("hex") + "\"") - - -class Slice(object): - def __init__(self, thing, start, end): - self.thing = thing - self.start = start - self.end = end - - def expr(self, stream, indent=" ", level=""): - self.thing.expr(stream, indent, level) - stream.write("[%d:%d]" % (self.start, self.end)) - - -class Concat(list): - def expr(self, stream, indent=" ", level=""): - stream.write("concat(\n") - for thing in self: - stream.write(level + indent) - thing.expr(stream, indent, level + indent) - stream.write(",\n") - stream.write(level + ")") - - -calls = [Call(c) for c in yaml.load(sys.stdin)] - -outputs = {} - -for call in calls: - for i in range(8, len(call.output)): - outputs.setdefault(call.output[i - 8: i], []).append(call) - -for call in calls: - for name, value in call.inputs.items(): - for bind in outputs.get(value[:8], ()): - if value == bind.output: - call.bind[name] = bind - else: - for end in range(len(value), len(bind.output) + 1): - start = end - len(value) - if value == bind.output[start:end]: - call.bind[name] = Slice(bind, start, end) - if not name in call.bind: - i = 0 - j = 1 - k = 0 - concat = Concat() - while i < len(value): - for bind in outputs.get(value[i:i+8], ()): - if value[i:].startswith(bind.output): - if k != i: - concat.append(Literal(value[k:i])) - concat.append(bind) - j = len(bind.output) - k = i + j - break - i += j - j = 1 - if concat: - if k != i: - concat.append(Literal(value[k:i])) - call.bind[name] = concat - -for call in calls: - if call.func.startswith("h"): - sys.stdout.write("\"" + call.output.encode("hex") + "\" = ") - call.expr(sys.stdout) - sys.stdout.write("\n") - diff --git a/tracing/trace.gdb b/tracing/trace.gdb deleted file mode 100644 index bdece2e..0000000 --- a/tracing/trace.gdb +++ /dev/null @@ -1,133 +0,0 @@ -set print pretty off -set print repeats unlimited -set print elements unlimited -set breakpoint pending on - - -break crypto.cpp:273 -commands -silent -printf "- hmac_sha256:\n" -printf " key_length: %d\n", key_length -printf " input_length: %d\n", input_length -if key_length > 0 - printf " key: " - output/x *key@key_length - printf "\n" -else - printf " key: {}\n" -end -if input_length > 0 - printf " input: " - output/x *input@input_length - printf "\n" -else - printf " input: {}\n" -end -cont -end - - -break crypto.cpp:280 -commands -silent -printf " output: " -output/x *output@32 -printf "\n" -cont -end - - -break crypto.cpp:307 -commands -silent -set $hkdf_output = output -cont -end - - -break crypto.cpp:323 -commands -silent -printf "- hkdf_sha256:\n" -printf " input_length: %d\n", input_length -printf " salt_length: %d\n", salt_length -printf " info_length: %d\n", info_length -printf " output_length: %d\n", output_length -if input_length > 0 - printf " input: " - output/x *input@input_length - printf "\n" -else - printf " input: {}\n" -end -if salt_length > 0 - printf " salt: " - output/x *salt@salt_length - printf "\n" -else - printf " salt: {}\n" -end -if info_length > 0 - printf " info: " - output/x *info@info_length - printf "\n" -else - printf " info: {}\n" -end -printf " output: " -output/x *$hkdf_output@output_length -printf "\n" -cont -end - - -break crypto.cpp:156 -commands -silent -printf "- curve25519:\n" -printf " public: " -output/x *their_key.public_key@32 -printf "\n" -printf " private: " -output/x *our_key.private_key@32 -printf "\n" -printf " output: " -output/x *output@32 -printf "\n" -cont -end - -break crypto.cpp:156 -commands -silent -printf "- curve25519:\n" -printf " public: " -output/x *their_key.public_key@32 -printf "\n" -printf " private: " -output/x *our_key.private_key@32 -printf "\n" -printf " output: " -output/x *output@32 -printf "\n" -cont -end - -break crypto.cpp:147 -commands -silent -printf "- curve25519:\n" -printf " public: " -output/x *CURVE25519_BASEPOINT@32 -printf "\n" -printf " private: " -output/x *key_pair.private_key@32 -printf "\n" -printf " output: " -output/x *key_pair.public_key@32 -printf "\n" -cont -end - -run diff --git a/version_script.ver b/version_script.ver deleted file mode 100644 index 3aec5f6..0000000 --- a/version_script.ver +++ /dev/null @@ -1,9 +0,0 @@ -# this is a 'version script' for the linker which tells it to only export -# symbols starting 'olm_'. - -{ - global: - olm_*; - local: - *; -}; diff --git a/xcode/OLMKit.xcodeproj/project.pbxproj b/xcode/OLMKit.xcodeproj/project.pbxproj deleted file mode 100644 index 821a204..0000000 --- a/xcode/OLMKit.xcodeproj/project.pbxproj +++ /dev/null @@ -1,510 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 3244277D2175EF700023EDF1 /* OLMKitPkTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3244277C2175EF700023EDF1 /* OLMKitPkTests.m */; }; - 3274F6021D9A633A005282E4 /* OLMKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3274F5F81D9A633A005282E4 /* OLMKit.framework */; }; - 3274F6071D9A633A005282E4 /* OLMKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3274F6061D9A633A005282E4 /* OLMKitTests.m */; }; - 3274F6131D9A698E005282E4 /* OLMKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 3274F6121D9A698E005282E4 /* OLMKit.h */; }; - 32A151311DABDD4300400192 /* OLMKitGroupTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 32A151301DABDD4300400192 /* OLMKitGroupTests.m */; }; - 32F143AF2236B4100077CF37 /* OLMKitSASTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 32F143AE2236B4100077CF37 /* OLMKitSASTests.m */; }; - 7DBAD311AEA85CF6DB80DCFA /* libPods-OLMKitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7123FABE917D0FB140E036B7 /* libPods-OLMKitTests.a */; }; - D667051A0BA47E17CCC4E5D7 /* libPods-OLMKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F2F22FE8F173AF845B882805 /* libPods-OLMKit.a */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 3274F6031D9A633A005282E4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 3274F5EF1D9A633A005282E4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3274F5F71D9A633A005282E4; - remoteInfo = OLMKit; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 1B226B371526F2782C9D6372 /* Pods-OLMKit.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OLMKit.release.xcconfig"; path = "Pods/Target Support Files/Pods-OLMKit/Pods-OLMKit.release.xcconfig"; sourceTree = "<group>"; }; - 3244277C2175EF700023EDF1 /* OLMKitPkTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OLMKitPkTests.m; sourceTree = "<group>"; }; - 3274F5F81D9A633A005282E4 /* OLMKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OLMKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 3274F5FC1D9A633A005282E4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; - 3274F6011D9A633A005282E4 /* OLMKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OLMKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 3274F6061D9A633A005282E4 /* OLMKitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OLMKitTests.m; sourceTree = "<group>"; }; - 3274F6081D9A633A005282E4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; - 3274F6121D9A698E005282E4 /* OLMKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OLMKit.h; sourceTree = "<group>"; }; - 32A151301DABDD4300400192 /* OLMKitGroupTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OLMKitGroupTests.m; sourceTree = "<group>"; }; - 32F143AE2236B4100077CF37 /* OLMKitSASTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OLMKitSASTests.m; sourceTree = "<group>"; }; - 7123FABE917D0FB140E036B7 /* libPods-OLMKitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-OLMKitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 875BA7A520258EA15A31DD82 /* Pods-OLMKitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OLMKitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-OLMKitTests/Pods-OLMKitTests.debug.xcconfig"; sourceTree = "<group>"; }; - D48E486DAE1F59F4F7EA8C25 /* Pods-OLMKitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OLMKitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-OLMKitTests/Pods-OLMKitTests.release.xcconfig"; sourceTree = "<group>"; }; - E50E6B16E3433A5EB3297DEE /* Pods-OLMKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OLMKit.debug.xcconfig"; path = "Pods/Target Support Files/Pods-OLMKit/Pods-OLMKit.debug.xcconfig"; sourceTree = "<group>"; }; - F2F22FE8F173AF845B882805 /* libPods-OLMKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-OLMKit.a"; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 3274F5F41D9A633A005282E4 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - D667051A0BA47E17CCC4E5D7 /* libPods-OLMKit.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3274F5FE1D9A633A005282E4 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 3274F6021D9A633A005282E4 /* OLMKit.framework in Frameworks */, - 7DBAD311AEA85CF6DB80DCFA /* libPods-OLMKitTests.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 1FA3F53DFAAAA773F07F5E56 /* Pods */ = { - isa = PBXGroup; - children = ( - E50E6B16E3433A5EB3297DEE /* Pods-OLMKit.debug.xcconfig */, - 1B226B371526F2782C9D6372 /* Pods-OLMKit.release.xcconfig */, - 875BA7A520258EA15A31DD82 /* Pods-OLMKitTests.debug.xcconfig */, - D48E486DAE1F59F4F7EA8C25 /* Pods-OLMKitTests.release.xcconfig */, - ); - name = Pods; - sourceTree = "<group>"; - }; - 3274F5EE1D9A633A005282E4 = { - isa = PBXGroup; - children = ( - 3274F5FA1D9A633A005282E4 /* OLMKit */, - 3274F6051D9A633A005282E4 /* OLMKitTests */, - 3274F5F91D9A633A005282E4 /* Products */, - 1FA3F53DFAAAA773F07F5E56 /* Pods */, - A5D2E6F079A29F7CC2A8D9FE /* Frameworks */, - ); - sourceTree = "<group>"; - }; - 3274F5F91D9A633A005282E4 /* Products */ = { - isa = PBXGroup; - children = ( - 3274F5F81D9A633A005282E4 /* OLMKit.framework */, - 3274F6011D9A633A005282E4 /* OLMKitTests.xctest */, - ); - name = Products; - sourceTree = "<group>"; - }; - 3274F5FA1D9A633A005282E4 /* OLMKit */ = { - isa = PBXGroup; - children = ( - 3274F6121D9A698E005282E4 /* OLMKit.h */, - 3274F5FC1D9A633A005282E4 /* Info.plist */, - ); - path = OLMKit; - sourceTree = "<group>"; - }; - 3274F6051D9A633A005282E4 /* OLMKitTests */ = { - isa = PBXGroup; - children = ( - 32F143AE2236B4100077CF37 /* OLMKitSASTests.m */, - 3244277C2175EF700023EDF1 /* OLMKitPkTests.m */, - 3274F6061D9A633A005282E4 /* OLMKitTests.m */, - 32A151301DABDD4300400192 /* OLMKitGroupTests.m */, - 3274F6081D9A633A005282E4 /* Info.plist */, - ); - path = OLMKitTests; - sourceTree = "<group>"; - }; - A5D2E6F079A29F7CC2A8D9FE /* Frameworks */ = { - isa = PBXGroup; - children = ( - F2F22FE8F173AF845B882805 /* libPods-OLMKit.a */, - 7123FABE917D0FB140E036B7 /* libPods-OLMKitTests.a */, - ); - name = Frameworks; - sourceTree = "<group>"; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 3274F5F51D9A633A005282E4 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 3274F6131D9A698E005282E4 /* OLMKit.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 3274F5F71D9A633A005282E4 /* OLMKit */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3274F60C1D9A633B005282E4 /* Build configuration list for PBXNativeTarget "OLMKit" */; - buildPhases = ( - 7FBCB292198F4156D9CA3B8D /* [CP] Check Pods Manifest.lock */, - 3274F5F31D9A633A005282E4 /* Sources */, - 3274F5F41D9A633A005282E4 /* Frameworks */, - 3274F5F51D9A633A005282E4 /* Headers */, - 3274F5F61D9A633A005282E4 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = OLMKit; - productName = OLMKit; - productReference = 3274F5F81D9A633A005282E4 /* OLMKit.framework */; - productType = "com.apple.product-type.framework"; - }; - 3274F6001D9A633A005282E4 /* OLMKitTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3274F60F1D9A633B005282E4 /* Build configuration list for PBXNativeTarget "OLMKitTests" */; - buildPhases = ( - 47E69E5BE6A019858DC41D4F /* [CP] Check Pods Manifest.lock */, - 3274F5FD1D9A633A005282E4 /* Sources */, - 3274F5FE1D9A633A005282E4 /* Frameworks */, - 3274F5FF1D9A633A005282E4 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 3274F6041D9A633A005282E4 /* PBXTargetDependency */, - ); - name = OLMKitTests; - productName = OLMKitTests; - productReference = 3274F6011D9A633A005282E4 /* OLMKitTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 3274F5EF1D9A633A005282E4 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0940; - ORGANIZATIONNAME = matrix.org; - TargetAttributes = { - 3274F5F71D9A633A005282E4 = { - CreatedOnToolsVersion = 8.0; - ProvisioningStyle = Automatic; - }; - 3274F6001D9A633A005282E4 = { - CreatedOnToolsVersion = 8.0; - ProvisioningStyle = Automatic; - }; - }; - }; - buildConfigurationList = 3274F5F21D9A633A005282E4 /* Build configuration list for PBXProject "OLMKit" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 3274F5EE1D9A633A005282E4; - productRefGroup = 3274F5F91D9A633A005282E4 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 3274F5F71D9A633A005282E4 /* OLMKit */, - 3274F6001D9A633A005282E4 /* OLMKitTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 3274F5F61D9A633A005282E4 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3274F5FF1D9A633A005282E4 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 47E69E5BE6A019858DC41D4F /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-OLMKitTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 7FBCB292198F4156D9CA3B8D /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-OLMKit-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 3274F5F31D9A633A005282E4 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3274F5FD1D9A633A005282E4 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3274F6071D9A633A005282E4 /* OLMKitTests.m in Sources */, - 32F143AF2236B4100077CF37 /* OLMKitSASTests.m in Sources */, - 3244277D2175EF700023EDF1 /* OLMKitPkTests.m in Sources */, - 32A151311DABDD4300400192 /* OLMKitGroupTests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 3274F6041D9A633A005282E4 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3274F5F71D9A633A005282E4 /* OLMKit */; - targetProxy = 3274F6031D9A633A005282E4 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 3274F60A1D9A633B005282E4 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 3274F60B1D9A633B005282E4 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - 3274F60D1D9A633B005282E4 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = E50E6B16E3433A5EB3297DEE /* Pods-OLMKit.debug.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = OLMKit/Info.plist; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = org.matrix.OLMKit; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - 3274F60E1D9A633B005282E4 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 1B226B371526F2782C9D6372 /* Pods-OLMKit.release.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = OLMKit/Info.plist; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = org.matrix.OLMKit; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Release; - }; - 3274F6101D9A633B005282E4 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 875BA7A520258EA15A31DD82 /* Pods-OLMKitTests.debug.xcconfig */; - buildSettings = { - INFOPLIST_FILE = OLMKitTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = org.matrix.OLMKitTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 3274F6111D9A633B005282E4 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D48E486DAE1F59F4F7EA8C25 /* Pods-OLMKitTests.release.xcconfig */; - buildSettings = { - INFOPLIST_FILE = OLMKitTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = org.matrix.OLMKitTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 3274F5F21D9A633A005282E4 /* Build configuration list for PBXProject "OLMKit" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3274F60A1D9A633B005282E4 /* Debug */, - 3274F60B1D9A633B005282E4 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3274F60C1D9A633B005282E4 /* Build configuration list for PBXNativeTarget "OLMKit" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3274F60D1D9A633B005282E4 /* Debug */, - 3274F60E1D9A633B005282E4 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3274F60F1D9A633B005282E4 /* Build configuration list for PBXNativeTarget "OLMKitTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3274F6101D9A633B005282E4 /* Debug */, - 3274F6111D9A633B005282E4 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 3274F5EF1D9A633A005282E4 /* Project object */; -} diff --git a/xcode/OLMKit/Info.plist b/xcode/OLMKit/Info.plist deleted file mode 100644 index d3de8ee..0000000 --- a/xcode/OLMKit/Info.plist +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>en</string> - <key>CFBundleExecutable</key> - <string>$(EXECUTABLE_NAME)</string> - <key>CFBundleIdentifier</key> - <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>$(PRODUCT_NAME)</string> - <key>CFBundlePackageType</key> - <string>FMWK</string> - <key>CFBundleShortVersionString</key> - <string>1.0</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>$(CURRENT_PROJECT_VERSION)</string> - <key>NSPrincipalClass</key> - <string></string> -</dict> -</plist> diff --git a/xcode/OLMKit/OLMAccount.h b/xcode/OLMKit/OLMAccount.h deleted file mode 100644 index c8d65cd..0000000 --- a/xcode/OLMKit/OLMAccount.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright 2016 Chris Ballinger - Copyright 2016 OpenMarket Ltd - Copyright 2016 Vector Creations 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. - */ - -#import <Foundation/Foundation.h> -#import "OLMSerializable.h" - -@class OLMSession; - -@interface OLMAccount : NSObject <OLMSerializable, NSSecureCoding> - -/** Creates new account */ -- (instancetype) initNewAccount; - -/** public identity keys. base64 encoded in "curve25519" and "ed25519" keys */ -- (NSDictionary*) identityKeys; - -/** signs message with ed25519 key for account */ -- (NSString*) signMessage:(NSData*)messageData; - -/** Public parts of the unpublished one time keys for the account */ -- (NSDictionary*) oneTimeKeys; - -- (BOOL) removeOneTimeKeysForSession:(OLMSession*)session; - -/** Marks the current set of one time keys as being published. */ -- (void) markOneTimeKeysAsPublished; - -/** The largest number of one time keys this account can store. */ -- (NSUInteger) maxOneTimeKeys; - -/** Generates a number of new one time keys. If the total number of keys stored - * by this account exceeds -maxOneTimeKeys then the old keys are - * discarded. */ -- (void) generateOneTimeKeys:(NSUInteger)numberOfKeys; - -@end diff --git a/xcode/OLMKit/OLMAccount.m b/xcode/OLMKit/OLMAccount.m deleted file mode 100644 index 9e48c2d..0000000 --- a/xcode/OLMKit/OLMAccount.m +++ /dev/null @@ -1,268 +0,0 @@ -/* - Copyright 2016 Chris Ballinger - Copyright 2016 OpenMarket Ltd - Copyright 2016 Vector Creations 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. - */ - -#import "OLMAccount.h" -#import "OLMAccount_Private.h" -#import "OLMSession.h" -#import "OLMSession_Private.h" -#import "OLMUtility.h" - -@import Security; - -@implementation OLMAccount - -- (void) dealloc { - olm_clear_account(_account); - free(_account); -} - -- (BOOL) initializeAccountMemory { - size_t accountSize = olm_account_size(); - _account = malloc(accountSize); - NSParameterAssert(_account != nil); - if (!_account) { - return NO; - } - _account = olm_account(_account); - NSParameterAssert(_account != nil); - if (!_account) { - return NO; - } - return YES; -} - -- (instancetype) init { - self = [super init]; - if (!self) { - return nil; - } - BOOL success = [self initializeAccountMemory]; - if (!success) { - return nil; - } - return self; -} - -- (instancetype) initNewAccount { - self = [self init]; - if (!self) { - return nil; - } - size_t randomLength = olm_create_account_random_length(_account); - NSMutableData *random = [OLMUtility randomBytesOfLength:randomLength]; - size_t accountResult = olm_create_account(_account, random.mutableBytes, random.length); - [random resetBytesInRange:NSMakeRange(0, random.length)]; - if (accountResult == olm_error()) { - const char *error = olm_account_last_error(_account); - NSLog(@"error creating account: %s", error); - return nil; - } - return self; -} - -- (NSUInteger) maxOneTimeKeys { - return olm_account_max_number_of_one_time_keys(_account); -} - - -/** public identity keys */ -- (NSDictionary*) identityKeys { - size_t identityKeysLength = olm_account_identity_keys_length(_account); - uint8_t *identityKeysBytes = malloc(identityKeysLength); - if (!identityKeysBytes) { - return nil; - } - size_t result = olm_account_identity_keys(_account, identityKeysBytes, identityKeysLength); - if (result == olm_error()) { - const char *error = olm_account_last_error(_account); - NSLog(@"error getting id keys: %s", error); - free(identityKeysBytes); - return nil; - } - NSData *idKeyData = [NSData dataWithBytesNoCopy:identityKeysBytes length:identityKeysLength freeWhenDone:YES]; - NSError *error = nil; - NSDictionary *keysDictionary = [NSJSONSerialization JSONObjectWithData:idKeyData options:0 error:&error]; - if (error) { - NSLog(@"Could not decode JSON: %@", error.localizedDescription); - } - return keysDictionary; -} - -- (NSString *)signMessage:(NSData *)messageData { - size_t signatureLength = olm_account_signature_length(_account); - uint8_t *signatureBytes = malloc(signatureLength); - if (!signatureBytes) { - return nil; - } - - size_t result = olm_account_sign(_account, messageData.bytes, messageData.length, signatureBytes, signatureLength); - if (result == olm_error()) { - const char *error = olm_account_last_error(_account); - NSLog(@"error signing message: %s", error); - free(signatureBytes); - return nil; - } - - NSData *signatureData = [NSData dataWithBytesNoCopy:signatureBytes length:signatureLength freeWhenDone:YES]; - return [[NSString alloc] initWithData:signatureData encoding:NSUTF8StringEncoding]; -} - -- (NSDictionary*) oneTimeKeys { - size_t otkLength = olm_account_one_time_keys_length(_account); - uint8_t *otkBytes = malloc(otkLength); - if (!otkBytes) { - return nil; - } - size_t result = olm_account_one_time_keys(_account, otkBytes, otkLength); - if (result == olm_error()) { - const char *error = olm_account_last_error(_account); - NSLog(@"error getting id keys: %s", error); - free(otkBytes); - return nil; - } - NSData *otk = [NSData dataWithBytesNoCopy:otkBytes length:otkLength freeWhenDone:YES]; - NSError *error = nil; - NSDictionary *keysDictionary = [NSJSONSerialization JSONObjectWithData:otk options:0 error:&error]; - if (error) { - NSLog(@"Could not decode JSON: %@", error.localizedDescription); - } - return keysDictionary; -} - - -- (void) generateOneTimeKeys:(NSUInteger)numberOfKeys { - size_t randomLength = olm_account_generate_one_time_keys_random_length(_account, numberOfKeys); - NSMutableData *random = [OLMUtility randomBytesOfLength:randomLength]; - size_t result = olm_account_generate_one_time_keys(_account, numberOfKeys, random.mutableBytes, random.length); - [random resetBytesInRange:NSMakeRange(0, random.length)]; - if (result == olm_error()) { - const char *error = olm_account_last_error(_account); - NSLog(@"error generating keys: %s", error); - } -} - -- (BOOL) removeOneTimeKeysForSession:(OLMSession *)session { - NSParameterAssert(session != nil); - if (!session) { - return NO; - } - size_t result = olm_remove_one_time_keys(self.account, session.session); - if (result == olm_error()) { - const char *error = olm_account_last_error(_account); - NSLog(@"olm_remove_one_time_keys error: %s", error); - return NO; - } - return YES; -} - -- (void)markOneTimeKeysAsPublished -{ - olm_account_mark_keys_as_published(self.account); -} - -#pragma mark OLMSerializable - -/** Initializes from encrypted serialized data. Will throw error if invalid key or invalid base64. */ -- (instancetype) initWithSerializedData:(NSString*)serializedData key:(NSData*)key error:(NSError**)error { - self = [self init]; - if (!self) { - return nil; - } - NSParameterAssert(key.length > 0); - NSParameterAssert(serializedData.length > 0); - if (key.length == 0 || serializedData.length == 0) { - if (error) { - *error = [NSError errorWithDomain:OLMErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey: @"Bad length."}]; - } - return nil; - } - NSMutableData *pickle = [serializedData dataUsingEncoding:NSUTF8StringEncoding].mutableCopy; - size_t result = olm_unpickle_account(_account, key.bytes, key.length, pickle.mutableBytes, pickle.length); - [pickle resetBytesInRange:NSMakeRange(0, pickle.length)]; - if (result == olm_error()) { - const char *olm_error = olm_account_last_error(_account); - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - if (error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey: errorString}]; - } - return nil; - } - return self; -} - -/** Serializes and encrypts object data, outputs base64 blob */ -- (NSString*) serializeDataWithKey:(NSData*)key error:(NSError**)error { - NSParameterAssert(key.length > 0); - size_t length = olm_pickle_account_length(_account); - NSMutableData *pickled = [NSMutableData dataWithLength:length]; - size_t result = olm_pickle_account(_account, key.bytes, key.length, pickled.mutableBytes, pickled.length); - if (result == olm_error()) { - const char *olm_error = olm_account_last_error(_account); - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - if (error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey: errorString}]; - } - return nil; - } - NSString *pickleString = [[NSString alloc] initWithData:pickled encoding:NSUTF8StringEncoding]; - [pickled resetBytesInRange:NSMakeRange(0, pickled.length)]; - return pickleString; -} - -#pragma mark NSSecureCoding - -+ (BOOL) supportsSecureCoding { - return YES; -} - -#pragma mark NSCoding - -- (id)initWithCoder:(NSCoder *)decoder { - NSString *version = [decoder decodeObjectOfClass:[NSString class] forKey:@"version"]; - - NSError *error = nil; - - if ([version isEqualToString:@"1"]) { - NSString *pickle = [decoder decodeObjectOfClass:[NSString class] forKey:@"pickle"]; - NSData *key = [decoder decodeObjectOfClass:[NSData class] forKey:@"key"]; - - self = [self initWithSerializedData:pickle key:key error:&error]; - } - - NSParameterAssert(error == nil); - NSParameterAssert(self != nil); - if (!self) { - return nil; - } - - return self; -} - -- (void)encodeWithCoder:(NSCoder *)encoder { - NSData *key = [OLMUtility randomBytesOfLength:32]; - NSError *error = nil; - NSString *pickle = [self serializeDataWithKey:key error:&error]; - NSParameterAssert(pickle.length > 0 && error == nil); - - [encoder encodeObject:pickle forKey:@"pickle"]; - [encoder encodeObject:key forKey:@"key"]; - [encoder encodeObject:@"1" forKey:@"version"]; -} - - -@end diff --git a/xcode/OLMKit/OLMAccount_Private.h b/xcode/OLMKit/OLMAccount_Private.h deleted file mode 100644 index 313ab71..0000000 --- a/xcode/OLMKit/OLMAccount_Private.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright 2016 Chris Ballinger - Copyright 2016 OpenMarket Ltd - Copyright 2016 Vector Creations 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. - */ - -#include "olm/olm.h" - -@interface OLMAccount() - -@property (nonatomic) OlmAccount *account; - -@end diff --git a/xcode/OLMKit/OLMInboundGroupSession.h b/xcode/OLMKit/OLMInboundGroupSession.h deleted file mode 100644 index c0d2c59..0000000 --- a/xcode/OLMKit/OLMInboundGroupSession.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright 2016 OpenMarket Ltd - Copyright 2016 Vector Creations 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. - */ - -#import <Foundation/Foundation.h> -#import "OLMSerializable.h" - -@interface OLMInboundGroupSession : NSObject <OLMSerializable, NSSecureCoding> - -- (instancetype)initInboundGroupSessionWithSessionKey:(NSString*)sessionKey error:(NSError**)error; - -- (instancetype)initInboundGroupSessionWithImportedSession:(NSString*)sessionKey error:(NSError**)error; - -- (NSString*)sessionIdentifier; - -/** base64 ciphertext -> UTF-8 plaintext */ -- (NSString*)decryptMessage:(NSString*)message messageIndex:(NSUInteger*)messageIndex error:(NSError**)error; - -- (NSUInteger)firstKnownIndex; - -- (BOOL)isVerified; - -- (NSString*)exportSessionAtMessageIndex:(NSUInteger)messageIndex error:(NSError**)error; - -@end diff --git a/xcode/OLMKit/OLMInboundGroupSession.m b/xcode/OLMKit/OLMInboundGroupSession.m deleted file mode 100644 index 9e57741..0000000 --- a/xcode/OLMKit/OLMInboundGroupSession.m +++ /dev/null @@ -1,301 +0,0 @@ -/* - Copyright 2016 OpenMarket Ltd - Copyright 2016 Vector Creations 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. - */ - -#import "OLMInboundGroupSession.h" - -#import "OLMUtility.h" -#include "olm/olm.h" - -@interface OLMInboundGroupSession () -{ - OlmInboundGroupSession *session; -} -@end - - -@implementation OLMInboundGroupSession - -- (void)dealloc { - olm_clear_inbound_group_session(session); - free(session); -} - -- (instancetype)init { - self = [super init]; - if (self) - { - session = malloc(olm_inbound_group_session_size()); - if (session) { - session = olm_inbound_group_session(session); - } - - if (!session) { - return nil; - } - } - return self; -} - -- (instancetype)initInboundGroupSessionWithSessionKey:(NSString *)sessionKey error:(NSError**)error { - self = [self init]; - if (self) { - NSData *sessionKeyData = [sessionKey dataUsingEncoding:NSUTF8StringEncoding]; - size_t result = olm_init_inbound_group_session(session, sessionKeyData.bytes, sessionKeyData.length); - if (result == olm_error()) { - const char *olm_error = olm_inbound_group_session_last_error(session); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - NSLog(@"olm_init_inbound_group_session error: %@", errorString); - - if (error && olm_error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_init_inbound_group_session error: %@", errorString] - }]; - } - - return nil; - } - } - return self; -} - -- (instancetype)initInboundGroupSessionWithImportedSession:(NSString *)sessionKey error:(NSError *__autoreleasing *)error -{ - self = [self init]; - if (self) { - NSData *sessionKeyData = [sessionKey dataUsingEncoding:NSUTF8StringEncoding]; - size_t result = olm_import_inbound_group_session(session, sessionKeyData.bytes, sessionKeyData.length); - if (result == olm_error()) { - const char *olm_error = olm_inbound_group_session_last_error(session); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - NSLog(@"olm_import_inbound_group_session error: %@", errorString); - - if (error && olm_error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_import_inbound_group_session error: %@", errorString] - }]; - } - - return nil; - } - } - return self; -} - -- (NSString *)sessionIdentifier { - size_t length = olm_inbound_group_session_id_length(session); - NSMutableData *idData = [NSMutableData dataWithLength:length]; - if (!idData) { - return nil; - } - size_t result = olm_inbound_group_session_id(session, idData.mutableBytes, idData.length); - if (result == olm_error()) { - const char *error = olm_inbound_group_session_last_error(session); - NSLog(@"olm_inbound_group_session_id error: %s", error); - return nil; - } - NSString *idString = [[NSString alloc] initWithData:idData encoding:NSUTF8StringEncoding]; - return idString; -} - -- (NSString *)decryptMessage:(NSString *)message messageIndex:(NSUInteger*)messageIndex error:(NSError**)error -{ - NSParameterAssert(message != nil); - NSData *messageData = [message dataUsingEncoding:NSUTF8StringEncoding]; - if (!messageData) { - return nil; - } - NSMutableData *mutMessage = messageData.mutableCopy; - size_t maxPlaintextLength = olm_group_decrypt_max_plaintext_length(session, mutMessage.mutableBytes, mutMessage.length); - if (maxPlaintextLength == olm_error()) { - const char *olm_error = olm_inbound_group_session_last_error(session); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - NSLog(@"olm_group_decrypt_max_plaintext_length error: %@", errorString); - - if (error && olm_error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_group_decrypt_max_plaintext_length error: %@", errorString] - }]; - } - - return nil; - } - // message buffer is destroyed by olm_group_decrypt_max_plaintext_length - mutMessage = messageData.mutableCopy; - NSMutableData *plaintextData = [NSMutableData dataWithLength:maxPlaintextLength]; - - uint32_t message_index; - size_t plaintextLength = olm_group_decrypt(session, mutMessage.mutableBytes, mutMessage.length, plaintextData.mutableBytes, plaintextData.length, &message_index); - if (plaintextLength == olm_error()) { - const char *olm_error = olm_inbound_group_session_last_error(session); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - NSLog(@"olm_group_decrypt error: %@", errorString); - - if (error && olm_error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_group_decrypt error: %@", errorString] - }]; - } - - return nil; - } - plaintextData.length = plaintextLength; - NSString *plaintext = [[NSString alloc] initWithData:plaintextData encoding:NSUTF8StringEncoding]; - [plaintextData resetBytesInRange:NSMakeRange(0, plaintextData.length)]; - - if (messageIndex) - { - *messageIndex = message_index; - } - - return plaintext; -} - -- (NSUInteger)firstKnownIndex -{ - return olm_inbound_group_session_first_known_index(session); -} - -- (BOOL)isVerified -{ - return (0 != olm_inbound_group_session_is_verified(session)); -} - -- (NSString*)exportSessionAtMessageIndex:(NSUInteger)messageIndex error:(NSError**)error; -{ - size_t length = olm_export_inbound_group_session_length(session); - NSMutableData *key = [NSMutableData dataWithLength:length]; - size_t result = olm_export_inbound_group_session(session, key.mutableBytes, key.length, (uint32_t)messageIndex); - if (result == olm_error()) { - const char *olm_error = olm_inbound_group_session_last_error(session); - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - if (error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey: errorString}]; - } - return nil; - } - NSString *keyString = [[NSString alloc] initWithData:key encoding:NSUTF8StringEncoding]; - [key resetBytesInRange:NSMakeRange(0, key.length)]; - return keyString; -} - - -#pragma mark OLMSerializable - -/** Initializes from encrypted serialized data. Will throw error if invalid key or invalid base64. */ -- (instancetype) initWithSerializedData:(NSString *)serializedData key:(NSData *)key error:(NSError *__autoreleasing *)error { - self = [self init]; - if (!self) { - return nil; - } - NSParameterAssert(key.length > 0); - NSParameterAssert(serializedData.length > 0); - if (key.length == 0 || serializedData.length == 0) { - if (error) { - *error = [NSError errorWithDomain:OLMErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey: @"Bad length."}]; - } - return nil; - } - NSMutableData *pickle = [serializedData dataUsingEncoding:NSUTF8StringEncoding].mutableCopy; - size_t result = olm_unpickle_inbound_group_session(session, key.bytes, key.length, pickle.mutableBytes, pickle.length); - [pickle resetBytesInRange:NSMakeRange(0, pickle.length)]; - if (result == olm_error()) { - const char *olm_error = olm_inbound_group_session_last_error(session); - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - if (error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey: errorString}]; - } - return nil; - } - return self; -} - -/** Serializes and encrypts object data, outputs base64 blob */ -- (NSString*) serializeDataWithKey:(NSData*)key error:(NSError**)error { - NSParameterAssert(key.length > 0); - size_t length = olm_pickle_inbound_group_session_length(session); - NSMutableData *pickled = [NSMutableData dataWithLength:length]; - size_t result = olm_pickle_inbound_group_session(session, key.bytes, key.length, pickled.mutableBytes, pickled.length); - if (result == olm_error()) { - const char *olm_error = olm_inbound_group_session_last_error(session); - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - if (error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey: errorString}]; - } - return nil; - } - NSString *pickleString = [[NSString alloc] initWithData:pickled encoding:NSUTF8StringEncoding]; - [pickled resetBytesInRange:NSMakeRange(0, pickled.length)]; - return pickleString; -} - -#pragma mark NSSecureCoding - -+ (BOOL) supportsSecureCoding { - return YES; -} - -#pragma mark NSCoding - -- (id)initWithCoder:(NSCoder *)decoder { - NSString *version = [decoder decodeObjectOfClass:[NSString class] forKey:@"version"]; - - NSError *error = nil; - - if ([version isEqualToString:@"1"]) { - NSString *pickle = [decoder decodeObjectOfClass:[NSString class] forKey:@"pickle"]; - NSData *key = [decoder decodeObjectOfClass:[NSData class] forKey:@"key"]; - - self = [self initWithSerializedData:pickle key:key error:&error]; - } - - NSParameterAssert(error == nil); - NSParameterAssert(self != nil); - if (!self) { - return nil; - } - - return self; -} - -- (void)encodeWithCoder:(NSCoder *)encoder { - NSData *key = [OLMUtility randomBytesOfLength:32]; - NSError *error = nil; - NSString *pickle = [self serializeDataWithKey:key error:&error]; - NSParameterAssert(pickle.length > 0 && error == nil); - - [encoder encodeObject:pickle forKey:@"pickle"]; - [encoder encodeObject:key forKey:@"key"]; - [encoder encodeObject:@"1" forKey:@"version"]; -} - -@end diff --git a/xcode/OLMKit/OLMKit.h b/xcode/OLMKit/OLMKit.h deleted file mode 100644 index 54496a0..0000000 --- a/xcode/OLMKit/OLMKit.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright 2016 Chris Ballinger - Copyright 2016 OpenMarket Ltd - Copyright 2016 Vector Creations 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. - */ - -#import <Foundation/Foundation.h> - -// In this header, you should import all the public headers of your framework using statements like #import <OLMKit/PublicHeader.h> - -#import <OLMKit/OLMAccount.h> -#import <OLMKit/OLMSession.h> -#import <OLMKit/OLMMessage.h> -#import <OLMKit/OLMUtility.h> -#import <OLMKit/OLMInboundGroupSession.h> -#import <OLMKit/OLMOutboundGroupSession.h> -#import <OLMKit/OLMPkEncryption.h> -#import <OLMKit/OLMPkDecryption.h> -#import <OLMKit/OLMPkSigning.h> -#import <OLMKit/OLMSAS.h> - -@interface OLMKit : NSObject - -//! Project version string for OLMKit, the same as libolm. -+ (NSString*)versionString; - -@end diff --git a/xcode/OLMKit/OLMKit.m b/xcode/OLMKit/OLMKit.m deleted file mode 100644 index c383650..0000000 --- a/xcode/OLMKit/OLMKit.m +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright 2016 OpenMarket Ltd - Copyright 2016 Vector Creations 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. - */ - -#import "OLMKit.h" - -#include "olm/olm.h" - -@implementation OLMKit - -+ (NSString*)versionString -{ - uint8_t major, minor, patch; - - olm_get_library_version(&major, &minor, &patch); - - return [NSString stringWithFormat:@"%tu.%tu.%tu", major, minor, patch]; -} - -@end diff --git a/xcode/OLMKit/OLMMessage.h b/xcode/OLMKit/OLMMessage.h deleted file mode 100644 index b6e8c8f..0000000 --- a/xcode/OLMKit/OLMMessage.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright 2016 Chris Ballinger - Copyright 2016 OpenMarket Ltd - Copyright 2016 Vector Creations 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. - */ - -#import <Foundation/Foundation.h> - -/* - from olm.hh - static const size_t OLM_MESSAGE_TYPE_PRE_KEY = 0; - static const size_t OLM_MESSAGE_TYPE_MESSAGE = 1; - */ -typedef NS_ENUM(NSInteger, OLMMessageType) { - OLMMessageTypePreKey = 0, - OLMMessageTypeMessage = 1 -}; - -@interface OLMMessage : NSObject - -@property (nonatomic, copy, readonly, nonnull) NSString *ciphertext; -@property (readonly) OLMMessageType type; - -- (nullable instancetype) initWithCiphertext:(nonnull NSString*)ciphertext type:(OLMMessageType)type; - -@end diff --git a/xcode/OLMKit/OLMMessage.m b/xcode/OLMKit/OLMMessage.m deleted file mode 100644 index 949f834..0000000 --- a/xcode/OLMKit/OLMMessage.m +++ /dev/null @@ -1,34 +0,0 @@ -/* - Copyright 2016 Chris Ballinger - Copyright 2016 OpenMarket Ltd - Copyright 2016 Vector Creations 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. - */ - -#import "OLMMessage.h" - -@implementation OLMMessage - -- (nullable instancetype) initWithCiphertext:(nonnull NSString*)ciphertext type:(OLMMessageType)type { - NSParameterAssert(ciphertext != nil); - self = [super init]; - if (!self) { - return nil; - } - _ciphertext = [ciphertext copy]; - _type = type; - return self; -} - -@end diff --git a/xcode/OLMKit/OLMOutboundGroupSession.h b/xcode/OLMKit/OLMOutboundGroupSession.h deleted file mode 100644 index c979b61..0000000 --- a/xcode/OLMKit/OLMOutboundGroupSession.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - Copyright 2016 OpenMarket Ltd - Copyright 2016 Vector Creations 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. - */ - -#import <Foundation/Foundation.h> -#import "OLMSerializable.h" - -@interface OLMOutboundGroupSession : NSObject <OLMSerializable, NSSecureCoding> - -- (instancetype) initOutboundGroupSession; - -- (NSString*)sessionIdentifier; -- (NSUInteger)messageIndex; -- (NSString*)sessionKey; - -/** UTF-8 plaintext -> base64 ciphertext */ -- (NSString*)encryptMessage:(NSString*)message error:(NSError**)error; - -@end diff --git a/xcode/OLMKit/OLMOutboundGroupSession.m b/xcode/OLMKit/OLMOutboundGroupSession.m deleted file mode 100644 index a0a7cc6..0000000 --- a/xcode/OLMKit/OLMOutboundGroupSession.m +++ /dev/null @@ -1,222 +0,0 @@ -/* - Copyright 2016 OpenMarket Ltd - Copyright 2016 Vector Creations 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. - */ - -#import "OLMOutboundGroupSession.h" - -#import "OLMUtility.h" -#include "olm/olm.h" - -@interface OLMOutboundGroupSession () -{ - OlmOutboundGroupSession *session; -} -@end - -@implementation OLMOutboundGroupSession - -- (void)dealloc { - olm_clear_outbound_group_session(session); - free(session); -} - -- (instancetype)init { - self = [super init]; - if (self) - { - session = malloc(olm_outbound_group_session_size()); - if (session) { - session = olm_outbound_group_session(session); - } - - if (!session) { - return nil; - } - } - return self; -} - -- (instancetype)initOutboundGroupSession { - self = [self init]; - if (self) { - NSMutableData *random = [OLMUtility randomBytesOfLength:olm_init_outbound_group_session_random_length(session)]; - - size_t result = olm_init_outbound_group_session(session, random.mutableBytes, random.length); - [random resetBytesInRange:NSMakeRange(0, random.length)]; - if (result == olm_error()) { - const char *error = olm_outbound_group_session_last_error(session); - NSLog(@"olm_init_outbound_group_session error: %s", error); - return nil; - } - } - return self; -} - -- (NSString *)sessionIdentifier { - size_t length = olm_outbound_group_session_id_length(session); - NSMutableData *idData = [NSMutableData dataWithLength:length]; - if (!idData) { - return nil; - } - size_t result = olm_outbound_group_session_id(session, idData.mutableBytes, idData.length); - if (result == olm_error()) { - const char *error = olm_outbound_group_session_last_error(session); - NSLog(@"olm_outbound_group_session_id error: %s", error); - return nil; - } - NSString *idString = [[NSString alloc] initWithData:idData encoding:NSUTF8StringEncoding]; - return idString; -} - -- (NSUInteger)messageIndex { - return olm_outbound_group_session_message_index(session); -} - -- (NSString *)sessionKey { - size_t length = olm_outbound_group_session_key_length(session); - NSMutableData *sessionKeyData = [NSMutableData dataWithLength:length]; - if (!sessionKeyData) { - return nil; - } - size_t result = olm_outbound_group_session_key(session, sessionKeyData.mutableBytes, sessionKeyData.length); - if (result == olm_error()) { - const char *error = olm_outbound_group_session_last_error(session); - NSLog(@"olm_outbound_group_session_key error: %s", error); - return nil; - } - NSString *sessionKey = [[NSString alloc] initWithData:sessionKeyData encoding:NSUTF8StringEncoding]; - [sessionKeyData resetBytesInRange:NSMakeRange(0, sessionKeyData.length)]; - return sessionKey; -} - -- (NSString *)encryptMessage:(NSString *)message error:(NSError**)error { - NSData *plaintextData = [message dataUsingEncoding:NSUTF8StringEncoding]; - size_t ciphertextLength = olm_group_encrypt_message_length(session, plaintextData.length); - NSMutableData *ciphertext = [NSMutableData dataWithLength:ciphertextLength]; - if (!ciphertext) { - return nil; - } - size_t result = olm_group_encrypt(session, plaintextData.bytes, plaintextData.length, ciphertext.mutableBytes, ciphertext.length); - if (result == olm_error()) { - const char *olm_error = olm_outbound_group_session_last_error(session); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - NSLog(@"olm_group_encrypt error: %@", errorString); - - if (error && olm_error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_group_encrypt error: %@", errorString] - }]; - } - - return nil; - } - return [[NSString alloc] initWithData:ciphertext encoding:NSUTF8StringEncoding]; -} - -#pragma mark OLMSerializable - -/** Initializes from encrypted serialized data. Will throw error if invalid key or invalid base64. */ -- (instancetype) initWithSerializedData:(NSString *)serializedData key:(NSData *)key error:(NSError *__autoreleasing *)error { - self = [self init]; - if (!self) { - return nil; - } - NSParameterAssert(key.length > 0); - NSParameterAssert(serializedData.length > 0); - if (key.length == 0 || serializedData.length == 0) { - if (error) { - *error = [NSError errorWithDomain:OLMErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey: @"Bad length."}]; - } - return nil; - } - NSMutableData *pickle = [serializedData dataUsingEncoding:NSUTF8StringEncoding].mutableCopy; - size_t result = olm_unpickle_outbound_group_session(session, key.bytes, key.length, pickle.mutableBytes, pickle.length); - [pickle resetBytesInRange:NSMakeRange(0, pickle.length)]; - if (result == olm_error()) { - const char *olm_error = olm_outbound_group_session_last_error(session); - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - if (error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey: errorString}]; - } - return nil; - } - return self; -} - -/** Serializes and encrypts object data, outputs base64 blob */ -- (NSString*) serializeDataWithKey:(NSData*)key error:(NSError**)error { - NSParameterAssert(key.length > 0); - size_t length = olm_pickle_outbound_group_session_length(session); - NSMutableData *pickled = [NSMutableData dataWithLength:length]; - size_t result = olm_pickle_outbound_group_session(session, key.bytes, key.length, pickled.mutableBytes, pickled.length); - if (result == olm_error()) { - const char *olm_error = olm_outbound_group_session_last_error(session); - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - if (error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey: errorString}]; - } - return nil; - } - NSString *pickleString = [[NSString alloc] initWithData:pickled encoding:NSUTF8StringEncoding]; - [pickled resetBytesInRange:NSMakeRange(0, pickled.length)]; - return pickleString; -} - -#pragma mark NSSecureCoding - -+ (BOOL) supportsSecureCoding { - return YES; -} - -#pragma mark NSCoding - -- (id)initWithCoder:(NSCoder *)decoder { - NSString *version = [decoder decodeObjectOfClass:[NSString class] forKey:@"version"]; - - NSError *error = nil; - - if ([version isEqualToString:@"1"]) { - NSString *pickle = [decoder decodeObjectOfClass:[NSString class] forKey:@"pickle"]; - NSData *key = [decoder decodeObjectOfClass:[NSData class] forKey:@"key"]; - - self = [self initWithSerializedData:pickle key:key error:&error]; - } - - NSParameterAssert(error == nil); - NSParameterAssert(self != nil); - if (!self) { - return nil; - } - - return self; -} - -- (void)encodeWithCoder:(NSCoder *)encoder { - NSData *key = [OLMUtility randomBytesOfLength:32]; - NSError *error = nil; - NSString *pickle = [self serializeDataWithKey:key error:&error]; - NSParameterAssert(pickle.length > 0 && error == nil); - - [encoder encodeObject:pickle forKey:@"pickle"]; - [encoder encodeObject:key forKey:@"key"]; - [encoder encodeObject:@"1" forKey:@"version"]; -} - -@end diff --git a/xcode/OLMKit/OLMPkDecryption.h b/xcode/OLMKit/OLMPkDecryption.h deleted file mode 100644 index 823dc78..0000000 --- a/xcode/OLMKit/OLMPkDecryption.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright 2018 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. - */ - -#import <Foundation/Foundation.h> - -#import "OLMSerializable.h" -#import "OLMPkMessage.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface OLMPkDecryption : NSObject <OLMSerializable, NSSecureCoding> - -/** - Initialise the key from the private part of a key as returned by `privateKey`. - - Note that the pubkey is a base64 encoded string, but the private key is - an unencoded byte array. - - @param privateKey the private key part. - @param error the error if any. - @return the associated public key. - */ -- (NSString *)setPrivateKey:(NSData*)privateKey error:(NSError* _Nullable *)error; - -/** - Generate a new key to use for decrypting messages. - - @param error the error if any. - @return the public part of the generated key. - */ -- (NSString *)generateKey:(NSError* _Nullable *)error; - -/** - Get the private key. - - @return the private key; - */ -- (NSData *)privateKey; - -/** - Decrypt a ciphertext. - - @param message the cipher message to decrypt. - @param error the error if any. - @return the decrypted message. - */ -- (NSString *)decryptMessage:(OLMPkMessage*)message error:(NSError* _Nullable *)error; - -/** - Private key length. - - @return the length in bytes. - */ -+ (NSUInteger)privateKeyLength; - -@end - -NS_ASSUME_NONNULL_END diff --git a/xcode/OLMKit/OLMPkDecryption.m b/xcode/OLMKit/OLMPkDecryption.m deleted file mode 100644 index 4af2c71..0000000 --- a/xcode/OLMKit/OLMPkDecryption.m +++ /dev/null @@ -1,299 +0,0 @@ -/* - Copyright 2018 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. - */ - -#import "OLMPkDecryption.h" - -#include "olm/olm.h" -#include "olm/pk.h" -#include "OLMUtility.h" - -@interface OLMPkDecryption () -{ - OlmPkDecryption *session; -} -@end - -@implementation OLMPkDecryption - -- (void)dealloc { - olm_clear_pk_decryption(session); - free(session); -} - -- (instancetype)init { - self = [super init]; - if (self) { - session = (OlmPkDecryption *)malloc(olm_pk_decryption_size()); - olm_pk_decryption(session); - } - return self; -} - -- (NSString *)setPrivateKey:(NSData *)privateKey error:(NSError *__autoreleasing _Nullable *)error { - size_t publicKeyLength = olm_pk_key_length(); - NSMutableData *publicKeyData = [NSMutableData dataWithLength:publicKeyLength]; - if (!publicKeyData) { - return nil; - } - - size_t result = olm_pk_key_from_private(session, - publicKeyData.mutableBytes, publicKeyLength, - (void*)privateKey.bytes, privateKey.length); - if (result == olm_error()) { - const char *olm_error = olm_pk_decryption_last_error(session); - NSLog(@"[OLMPkDecryption] setPrivateKey: olm_pk_key_from_private error: %s", olm_error); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - if (error && olm_error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_pk_key_from_private error: %@", errorString] - }]; - } - return nil; - } - - NSString *publicKey = [[NSString alloc] initWithData:publicKeyData encoding:NSUTF8StringEncoding]; - return publicKey; -} - -- (NSString *)generateKey:(NSError *__autoreleasing _Nullable *)error { - size_t randomLength = olm_pk_private_key_length(); - NSMutableData *random = [OLMUtility randomBytesOfLength:randomLength]; - if (!random) { - return nil; - } - - size_t publicKeyLength = olm_pk_key_length(); - NSMutableData *publicKeyData = [NSMutableData dataWithLength:publicKeyLength]; - if (!publicKeyData) { - return nil; - } - - size_t result = olm_pk_key_from_private(session, - publicKeyData.mutableBytes, publicKeyData.length, - random.mutableBytes, randomLength); - [random resetBytesInRange:NSMakeRange(0, randomLength)]; - if (result == olm_error()) { - const char *olm_error = olm_pk_decryption_last_error(session); - NSLog(@"[OLMPkDecryption] generateKey: olm_pk_key_from_private error: %s", olm_error); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - if (error && olm_error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_pk_key_from_private error: %@", errorString] - }]; - } - return nil; - } - - NSString *publicKey = [[NSString alloc] initWithData:publicKeyData encoding:NSUTF8StringEncoding]; - return publicKey; -} - -- (NSData *)privateKey { - size_t privateKeyLength = olm_pk_private_key_length(); - NSMutableData *privateKeyData = [NSMutableData dataWithLength:privateKeyLength]; - if (!privateKeyData) { - return nil; - } - - size_t result = olm_pk_get_private_key(session, - privateKeyData.mutableBytes, privateKeyLength); - if (result == olm_error()) { - const char *olm_error = olm_pk_decryption_last_error(session); - NSLog(@"[OLMPkDecryption] privateKey: olm_pk_get_private_key error: %s", olm_error); - return nil; - } - - NSData *privateKey = [privateKeyData copy]; - [privateKeyData resetBytesInRange:NSMakeRange(0, privateKeyData.length)]; - - return privateKey; -} - -- (NSString *)decryptMessage:(OLMPkMessage *)message error:(NSError *__autoreleasing _Nullable *)error { - NSData *messageData = [message.ciphertext dataUsingEncoding:NSUTF8StringEncoding]; - NSData *macData = [message.mac dataUsingEncoding:NSUTF8StringEncoding]; - NSData *ephemeralKeyData = [message.ephemeralKey dataUsingEncoding:NSUTF8StringEncoding]; - if (!messageData || !macData || !ephemeralKeyData) { - return nil; - } - - NSMutableData *mutMessage = messageData.mutableCopy; - size_t maxPlaintextLength = olm_pk_max_plaintext_length(session, mutMessage.length); - if (maxPlaintextLength == olm_error()) { - const char *olm_error = olm_pk_decryption_last_error(session); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - NSLog(@"[OLMPkDecryption] decryptMessage: olm_pk_max_plaintext_length error: %@", errorString); - - if (error && olm_error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_pk_max_plaintext_length error: %@", errorString] - }]; - } - - return nil; - } - - mutMessage = messageData.mutableCopy; - NSMutableData *plaintextData = [NSMutableData dataWithLength:maxPlaintextLength]; - size_t plaintextLength = olm_pk_decrypt(session, - ephemeralKeyData.bytes, ephemeralKeyData.length, - macData.bytes, macData.length, - mutMessage.mutableBytes, mutMessage.length, - plaintextData.mutableBytes, plaintextData.length); - if (plaintextLength == olm_error()) { - const char *olm_error = olm_pk_decryption_last_error(session); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - NSLog(@"[OLMPkDecryption] decryptMessage: olm_pk_decrypt error: %@", errorString); - - if (error && olm_error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_decrypt error: %@", errorString] - }]; - } - - return nil; - } - - plaintextData.length = plaintextLength; - NSString *plaintext = [[NSString alloc] initWithData:plaintextData encoding:NSUTF8StringEncoding]; - [plaintextData resetBytesInRange:NSMakeRange(0, plaintextData.length)]; - return plaintext; -} - -+ (NSUInteger)privateKeyLength { - return olm_pk_private_key_length(); -} - -#pragma mark OLMSerializable - -/** Initializes from encrypted serialized data. Will throw error if invalid key or invalid base64. */ -- (instancetype) initWithSerializedData:(NSString *)serializedData key:(NSData *)key error:(NSError *__autoreleasing *)error { - self = [self init]; - if (!self) { - return nil; - } - - NSParameterAssert(key.length > 0); - NSParameterAssert(serializedData.length > 0); - if (key.length == 0 || serializedData.length == 0) { - if (error) { - *error = [NSError errorWithDomain:OLMErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey: @"Bad length."}]; - } - return nil; - } - - size_t ephemeralLength = olm_pk_key_length(); - NSMutableData *ephemeralBuffer = [NSMutableData dataWithLength:ephemeralLength]; - - NSMutableData *pickle = [serializedData dataUsingEncoding:NSUTF8StringEncoding].mutableCopy; - size_t result = olm_unpickle_pk_decryption(session, - key.bytes, key.length, - pickle.mutableBytes, pickle.length, - ephemeralBuffer.mutableBytes, ephemeralLength); - [pickle resetBytesInRange:NSMakeRange(0, pickle.length)]; - if (result == olm_error()) { - const char *olm_error = olm_pk_decryption_last_error(session); - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - if (error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey: errorString}]; - } - return nil; - } - return self; -} - -/** Serializes and encrypts object data, outputs base64 blob */ -- (NSString*) serializeDataWithKey:(NSData*)key error:(NSError**)error { - NSParameterAssert(key.length > 0); - size_t length = olm_pickle_pk_decryption_length(session); - NSMutableData *pickled = [NSMutableData dataWithLength:length]; - - size_t result = olm_pickle_pk_decryption(session, - key.bytes, key.length, - pickled.mutableBytes, pickled.length); - if (result == olm_error()) { - const char *olm_error = olm_pk_decryption_last_error(session); - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - if (error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey: errorString}]; - } - return nil; - } - - NSString *pickleString = [[NSString alloc] initWithData:pickled encoding:NSUTF8StringEncoding]; - [pickled resetBytesInRange:NSMakeRange(0, pickled.length)]; - - return pickleString; -} - -#pragma mark NSSecureCoding - -+ (BOOL) supportsSecureCoding { - return YES; -} - -#pragma mark NSCoding - -- (id)initWithCoder:(NSCoder *)decoder { - NSString *version = [decoder decodeObjectOfClass:[NSString class] forKey:@"version"]; - - NSError *error = nil; - - if ([version isEqualToString:@"1"]) { - NSString *pickle = [decoder decodeObjectOfClass:[NSString class] forKey:@"pickle"]; - NSData *key = [decoder decodeObjectOfClass:[NSData class] forKey:@"key"]; - - self = [self initWithSerializedData:pickle key:key error:&error]; - } - - NSParameterAssert(error == nil); - NSParameterAssert(self != nil); - if (!self) { - return nil; - } - - return self; -} - -- (void)encodeWithCoder:(NSCoder *)encoder { - NSData *key = [OLMUtility randomBytesOfLength:32]; - NSError *error = nil; - - NSString *pickle = [self serializeDataWithKey:key error:&error]; - NSParameterAssert(pickle.length > 0 && error == nil); - - [encoder encodeObject:pickle forKey:@"pickle"]; - [encoder encodeObject:key forKey:@"key"]; - [encoder encodeObject:@"1" forKey:@"version"]; -} - -@end diff --git a/xcode/OLMKit/OLMPkEncryption.h b/xcode/OLMKit/OLMPkEncryption.h deleted file mode 100644 index 6ae767c..0000000 --- a/xcode/OLMKit/OLMPkEncryption.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright 2018 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. - */ - -#import <Foundation/Foundation.h> - -#import "OLMPkMessage.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface OLMPkEncryption : NSObject - -/** - Set the recipient's public key for encrypting to. - - @param recipientKey the recipient's public key. - */ -- (void)setRecipientKey:(NSString*)recipientKey; - -/** - Encrypt a plaintext for the recipient. - - @param message the message to encrypt. - @param error the error if any. - @return the encrypted message. - */ -- (OLMPkMessage *)encryptMessage:(NSString*)message error:(NSError* _Nullable *)error; - -@end - -NS_ASSUME_NONNULL_END diff --git a/xcode/OLMKit/OLMPkEncryption.m b/xcode/OLMKit/OLMPkEncryption.m deleted file mode 100644 index 34ad57c..0000000 --- a/xcode/OLMKit/OLMPkEncryption.m +++ /dev/null @@ -1,111 +0,0 @@ -/* - Copyright 2018 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. - */ - -#import "OLMPkEncryption.h" - -#include "olm/olm.h" -#include "olm/pk.h" -#include "OLMUtility.h" - -@interface OLMPkEncryption () -{ - OlmPkEncryption *session; -} -@end - -@implementation OLMPkEncryption - -- (void)dealloc { - olm_clear_pk_encryption(session); - free(session); -} - - -- (instancetype)init { - self = [super init]; - if (self) { - session = (OlmPkEncryption *)malloc(olm_pk_encryption_size()); - olm_pk_encryption(session); - } - return self; -} - -- (void)setRecipientKey:(NSString*)recipientKey { - NSData *recipientKeyData = [recipientKey dataUsingEncoding:NSUTF8StringEncoding]; - olm_pk_encryption_set_recipient_key(session, recipientKeyData.bytes, recipientKeyData.length); -} - -- (OLMPkMessage *)encryptMessage:(NSString *)message error:(NSError *__autoreleasing _Nullable *)error { - NSData *plaintextData = [message dataUsingEncoding:NSUTF8StringEncoding]; - - size_t randomLength = olm_pk_encrypt_random_length(session); - NSMutableData *random = [OLMUtility randomBytesOfLength:randomLength]; - if (!random) { - return nil; - } - - size_t ciphertextLength = olm_pk_ciphertext_length(session, plaintextData.length); - NSMutableData *ciphertext = [NSMutableData dataWithLength:ciphertextLength]; - if (!ciphertext) { - return nil; - } - - size_t macLength = olm_pk_mac_length(session); - NSMutableData *macData = [NSMutableData dataWithLength:macLength]; - if (!macData) { - return nil; - } - - size_t ephemeralKeyLength = olm_pk_key_length(); - NSMutableData *ephemeralKeyData = [NSMutableData dataWithLength:ephemeralKeyLength]; - if (!ephemeralKeyData) { - return nil; - } - - size_t result = olm_pk_encrypt(session, - plaintextData.bytes, plaintextData.length, - ciphertext.mutableBytes, ciphertext.length, - macData.mutableBytes, macLength, - ephemeralKeyData.mutableBytes, ephemeralKeyLength, - random.mutableBytes, randomLength); - if (result == olm_error()) { - const char *olm_error = olm_pk_encryption_last_error(session); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - NSLog(@"[OLMPkEncryption] encryptMessage: olm_group_encrypt error: %@", errorString); - - if (error && olm_error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_group_encrypt error: %@", errorString] - }]; - } - - return nil; - } - - OLMPkMessage *encryptedMessage = [[OLMPkMessage alloc] - initWithCiphertext:[[NSString alloc] initWithData:ciphertext encoding:NSUTF8StringEncoding] - mac:[[NSString alloc] initWithData:macData encoding:NSUTF8StringEncoding] - ephemeralKey:[[NSString alloc] initWithData:ephemeralKeyData encoding:NSUTF8StringEncoding]]; - - - return encryptedMessage; -} - -@end diff --git a/xcode/OLMKit/OLMPkMessage.h b/xcode/OLMKit/OLMPkMessage.h deleted file mode 100644 index 1559fca..0000000 --- a/xcode/OLMKit/OLMPkMessage.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright 2018 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. - */ - -#import <Foundation/Foundation.h> - -NS_ASSUME_NONNULL_BEGIN - -@interface OLMPkMessage : NSObject - -@property (nonatomic, copy, readonly) NSString *ciphertext; -@property (nonatomic, copy, readonly,) NSString *mac; -@property (nonatomic, copy, readonly) NSString *ephemeralKey; - -- (instancetype) initWithCiphertext:(NSString*)ciphertext mac:(NSString*)mac ephemeralKey:(NSString*)ephemeralKey; - -@end - -NS_ASSUME_NONNULL_END diff --git a/xcode/OLMKit/OLMPkMessage.m b/xcode/OLMKit/OLMPkMessage.m deleted file mode 100644 index 0f24512..0000000 --- a/xcode/OLMKit/OLMPkMessage.m +++ /dev/null @@ -1,32 +0,0 @@ -/* - Copyright 2018 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. - */ - -#import "OLMPkMessage.h" - -@implementation OLMPkMessage - -- (instancetype)initWithCiphertext:(NSString *)ciphertext mac:(NSString *)mac ephemeralKey:(NSString *)ephemeralKey { - self = [super init]; - if (!self) { - return nil; - } - _ciphertext = [ciphertext copy]; - _mac = [mac copy]; - _ephemeralKey = [ephemeralKey copy]; - return self; -} - -@end diff --git a/xcode/OLMKit/OLMPkSigning.h b/xcode/OLMKit/OLMPkSigning.h deleted file mode 100644 index 09724e1..0000000 --- a/xcode/OLMKit/OLMPkSigning.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - Copyright 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. - */ - -#import <Foundation/Foundation.h> - -NS_ASSUME_NONNULL_BEGIN - -@interface OLMPkSigning : NSObject - -/** - Initialise the signing object with a public/private keypair from a seed. - - @param seed the seed. - @param error the error if any. - @return the public key - */ -- (NSString *)doInitWithSeed:(NSData*)seed error:(NSError* _Nullable *)error; - -/** - Sign a message. - - @param message the message to sign. - @param error the error if any. - @return the signature. - */ -- (NSString *)sign:(NSString*)message error:(NSError* _Nullable *)error; - -/** - Generate a seed. - - @return the generated seed. - */ -+ (NSData *)generateSeed; - -@end - -NS_ASSUME_NONNULL_END diff --git a/xcode/OLMKit/OLMPkSigning.m b/xcode/OLMKit/OLMPkSigning.m deleted file mode 100644 index d5c7d09..0000000 --- a/xcode/OLMKit/OLMPkSigning.m +++ /dev/null @@ -1,125 +0,0 @@ -/* - Copyright 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. - */ - -#import "OLMPkSigning.h" - -#include "olm/olm.h" -#include "olm/pk.h" -#include "OLMUtility.h" - -@interface OLMPkSigning () -{ - OlmPkSigning *sign; -} -@end - -@implementation OLMPkSigning - -- (void)dealloc { - olm_clear_pk_signing(sign); - free(sign); -} - - -- (instancetype)init { - self = [super init]; - if (self) { - sign = (OlmPkSigning *)malloc(olm_pk_signing_size()); - olm_pk_signing(sign); - } - return self; -} - -- (NSString *)doInitWithSeed:(NSData *)seed error:(NSError *__autoreleasing _Nullable *)error { - size_t publicKeyLength = olm_pk_signing_public_key_length(); - NSMutableData *publicKeyData = [NSMutableData dataWithLength:publicKeyLength]; - if (!publicKeyData) { - return nil; - } - - NSMutableData *mutableSeed = [NSMutableData dataWithData:seed]; - - size_t result = olm_pk_signing_key_from_seed(sign, - publicKeyData.mutableBytes, publicKeyLength, - mutableSeed.mutableBytes, mutableSeed.length); - if (result == olm_error()) { - const char *olm_error = olm_pk_signing_last_error(sign); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - NSLog(@"[OLMPkSigning] doInitWithSeed: olm_pk_signing_key_from_seed error: %@", errorString); - - if (error && olm_error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_pk_signing_key_from_seed error: %@", errorString] - }]; - } - - return nil; - } - - [mutableSeed resetBytesInRange:NSMakeRange(0, mutableSeed.length)]; - - NSString *publicKey = [[NSString alloc] initWithData:publicKeyData encoding:NSUTF8StringEncoding]; - return publicKey; -} - -- (NSString *)sign:(NSString *)message error:(NSError *__autoreleasing _Nullable *)error { - NSData *messageData = [message dataUsingEncoding:NSUTF8StringEncoding]; - - size_t signatureLength = olm_pk_signature_length(); - NSMutableData *signatureData = [NSMutableData dataWithLength:signatureLength]; - if (!signatureData) { - return nil; - } - - size_t result = olm_pk_sign(sign, - messageData.bytes, messageData.length, - signatureData.mutableBytes, signatureLength); - if (result == olm_error()) { - const char *olm_error = olm_pk_signing_last_error(sign); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - NSLog(@"[OLMPkSigning] sign: olm_pk_sign error: %@", errorString); - - if (error && olm_error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_pk_sign error: %@", errorString] - }]; - } - - return nil; - } - - NSString *signature = [[NSString alloc] initWithData:signatureData encoding:NSUTF8StringEncoding]; - return signature; -} - -+ (NSData *)generateSeed { - size_t seedLength = olm_pk_signing_seed_length(); - NSMutableData *seed = [OLMUtility randomBytesOfLength:seedLength]; - if (!seed) { - return nil; - } - - return seed; -} - -@end diff --git a/xcode/OLMKit/OLMSAS.h b/xcode/OLMKit/OLMSAS.h deleted file mode 100644 index 3785b03..0000000 --- a/xcode/OLMKit/OLMSAS.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - Copyright 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. - */ - -#import <Foundation/Foundation.h> - -NS_ASSUME_NONNULL_BEGIN - -/** - Short Authentication String verification utility class. - */ -@interface OLMSAS : NSObject - -/** - Get the public key of the SAS object. - */ -- (NSString * _Nullable)publicKey; - -/** - Set the public key of other user. - - @param theirPublicKey the other user's public key. - @return error the error if any. - */ -- (NSError* _Nullable)setTheirPublicKey:(NSString*)theirPublicKey; - -/** - Generate bytes to use for the short authentication string. - - @param info extra information to mix in when generating the bytes, as per the Matrix spec. - @param length the size of the output buffer. For hex-based SAS as in the Matrix spec, this will be 5. - @return generated bytes - */ -- (NSData *)generateBytes:(NSString*)info length:(NSUInteger)length; - -/** - Generate a message authentication code (MAC) based on the shared secret. - - @param input the message to produce the authentication code for. - @param info extra information to mix in when generating the MAC, as per the Matrix spec. - @param error the error if any. - @return the MAC. - */ -- (NSString *)calculateMac:(NSString*)input info:(NSString*)info error:(NSError* _Nullable *)error; - -/** - Generate a message authentication code (MAC) based on the shared secret. - For compatibility with an old version of olm.js. - - @param input the message to produce the authentication code for. - @param info extra information to mix in when generating the MAC, as per the Matrix spec. - @param error the error if any. - @return the MAC. - */ -- (NSString *)calculateMacLongKdf:(NSString*)input info:(NSString*)info error:(NSError* _Nullable *)error; - -@end - -NS_ASSUME_NONNULL_END diff --git a/xcode/OLMKit/OLMSAS.m b/xcode/OLMKit/OLMSAS.m deleted file mode 100644 index fed370b..0000000 --- a/xcode/OLMKit/OLMSAS.m +++ /dev/null @@ -1,174 +0,0 @@ -/* - Copyright 2018 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. - */ - -#import "OLMSAS.h" - -#include "olm/olm.h" -#include "olm/sas.h" -#include "OLMUtility.h" - -@interface OLMSAS () { - void *olmSASbuffer; - OlmSAS *olmSAS; -} -@end - -@implementation OLMSAS - -- (void)dealloc { - olm_clear_sas(olmSAS); - free(olmSASbuffer); -} - -- (instancetype)init { - self = [super init]; - if (self) { - olmSASbuffer = malloc(olm_sas_size()); - olmSAS = olm_sas(olmSASbuffer); - - size_t randomLength = olm_create_sas_random_length(olmSAS); - NSMutableData *random = [OLMUtility randomBytesOfLength:randomLength]; - if (!random) { - return nil; - } - - olm_create_sas(olmSAS, random.mutableBytes, randomLength); - - [random resetBytesInRange:NSMakeRange(0, randomLength)]; - } - return self; -} - -- (NSString * _Nullable)publicKey { - size_t publicKeyLength = olm_sas_pubkey_length(olmSAS); - NSMutableData *publicKeyData = [NSMutableData dataWithLength:publicKeyLength]; - if (!publicKeyData) { - return nil; - } - - size_t result = olm_sas_get_pubkey(olmSAS, publicKeyData.mutableBytes, publicKeyLength); - if (result == olm_error()) { - const char *olm_error = olm_sas_last_error(olmSAS); - NSLog(@"[OLMSAS] publicKey: olm_sas_get_pubkey error: %s", olm_error); - return nil; - } - - NSString *publicKey = [[NSString alloc] initWithData:publicKeyData encoding:NSUTF8StringEncoding]; - return publicKey; -} - -- (NSError * _Nullable)setTheirPublicKey:(NSString*)theirPublicKey { - NSMutableData *theirPublicKeyData = [theirPublicKey dataUsingEncoding:NSUTF8StringEncoding].mutableCopy; - - size_t result = olm_sas_set_their_key(olmSAS, theirPublicKeyData.mutableBytes, theirPublicKeyData.length); - if (result == olm_error()) { - const char *olm_error = olm_sas_last_error(olmSAS); - NSLog(@"[OLMSAS] setTheirPublicKey: olm_sas_set_their_key error: %s", olm_error); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - if (olm_error && errorString) { - return [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_sas_set_their_key error: %@", errorString] - }]; - } - } - - return nil; -} - -- (NSData *)generateBytes:(NSString *)info length:(NSUInteger)length { - NSData *infoData = [info dataUsingEncoding:NSUTF8StringEncoding]; - - NSMutableData *bytes = [NSMutableData dataWithLength:length]; - if (!bytes) { - return nil; - } - - olm_sas_generate_bytes(olmSAS, infoData.bytes, infoData.length, bytes.mutableBytes, length); - return bytes; -} - -- (NSString *)calculateMac:(NSString *)input info:(NSString *)info error:(NSError *__autoreleasing _Nullable *)error { - NSMutableData *inputData = [input dataUsingEncoding:NSUTF8StringEncoding].mutableCopy; - NSData *infoData = [info dataUsingEncoding:NSUTF8StringEncoding]; - - size_t macLength = olm_sas_mac_length(olmSAS); - NSMutableData *macData = [NSMutableData dataWithLength:macLength]; - if (!macData) { - return nil; - } - - size_t result = olm_sas_calculate_mac(olmSAS, - inputData.mutableBytes, inputData.length, - infoData.bytes, infoData.length, - macData.mutableBytes, macLength); - if (result == olm_error()) { - const char *olm_error = olm_sas_last_error(olmSAS); - NSLog(@"[OLMSAS] calculateMac: olm_sas_calculate_mac error: %s", olm_error); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - if (error && olm_error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_sas_calculate_mac error: %@", errorString] - }]; - } - return nil; - } - - NSString *mac = [[NSString alloc] initWithData:macData encoding:NSUTF8StringEncoding]; - return mac; -} - -- (NSString *)calculateMacLongKdf:(NSString *)input info:(NSString *)info error:(NSError *__autoreleasing _Nullable *)error { - NSMutableData *inputData = [input dataUsingEncoding:NSUTF8StringEncoding].mutableCopy; - NSData *infoData = [info dataUsingEncoding:NSUTF8StringEncoding]; - - size_t macLength = olm_sas_mac_length(olmSAS); - NSMutableData *macData = [NSMutableData dataWithLength:macLength]; - if (!macData) { - return nil; - } - - size_t result = olm_sas_calculate_mac_long_kdf(olmSAS, - inputData.mutableBytes, inputData.length, - infoData.bytes, infoData.length, - macData.mutableBytes, macLength); - if (result == olm_error()) { - const char *olm_error = olm_sas_last_error(olmSAS); - NSLog(@"[OLMSAS] calculateMacLongKdf: olm_sas_calculate_mac error: %s", olm_error); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - if (error && olm_error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_sas_calculate_mac_long_kdf error: %@", errorString] - }]; - } - return nil; - } - - NSString *mac = [[NSString alloc] initWithData:macData encoding:NSUTF8StringEncoding]; - return mac; -} - -@end diff --git a/xcode/OLMKit/OLMSerializable.h b/xcode/OLMKit/OLMSerializable.h deleted file mode 100644 index e929903..0000000 --- a/xcode/OLMKit/OLMSerializable.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright 2016 Chris Ballinger - Copyright 2016 OpenMarket Ltd - Copyright 2016 Vector Creations 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. - */ - -#import <Foundation/Foundation.h> - -@protocol OLMSerializable <NSObject> - -/** Initializes from encrypted serialized data. Will throw error if invalid key or invalid base64. */ -- (instancetype) initWithSerializedData:(NSString*)serializedData key:(NSData*)key error:(NSError**)error; - -/** Serializes and encrypts object data, outputs base64 blob */ -- (NSString*) serializeDataWithKey:(NSData*)key error:(NSError**)error; - -@end diff --git a/xcode/OLMKit/OLMSession.h b/xcode/OLMKit/OLMSession.h deleted file mode 100644 index 0446f98..0000000 --- a/xcode/OLMKit/OLMSession.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright 2016 Chris Ballinger - Copyright 2016 OpenMarket Ltd - Copyright 2016 Vector Creations 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. - */ - -#import <Foundation/Foundation.h> -#import "OLMSerializable.h" -#import "OLMAccount.h" -#import "OLMMessage.h" - -@interface OLMSession : NSObject <OLMSerializable, NSSecureCoding> - -- (instancetype) initOutboundSessionWithAccount:(OLMAccount*)account theirIdentityKey:(NSString*)theirIdentityKey theirOneTimeKey:(NSString*)theirOneTimeKey error:(NSError**)error; - -- (instancetype) initInboundSessionWithAccount:(OLMAccount*)account oneTimeKeyMessage:(NSString*)oneTimeKeyMessage error:(NSError**)error; - -- (instancetype) initInboundSessionWithAccount:(OLMAccount*)account theirIdentityKey:(NSString*)theirIdentityKey oneTimeKeyMessage:(NSString*)oneTimeKeyMessage error:(NSError**)error; - -- (NSString*) sessionIdentifier; - -- (BOOL) matchesInboundSession:(NSString*)oneTimeKeyMessage; - -- (BOOL) matchesInboundSessionFrom:(NSString*)theirIdentityKey oneTimeKeyMessage:(NSString *)oneTimeKeyMessage; - -/** UTF-8 plaintext -> base64 ciphertext */ -- (OLMMessage*) encryptMessage:(NSString*)message error:(NSError**)error; - -/** base64 ciphertext -> UTF-8 plaintext */ -- (NSString*) decryptMessage:(OLMMessage*)message error:(NSError**)error; - -@end diff --git a/xcode/OLMKit/OLMSession.m b/xcode/OLMKit/OLMSession.m deleted file mode 100644 index fc58a08..0000000 --- a/xcode/OLMKit/OLMSession.m +++ /dev/null @@ -1,383 +0,0 @@ -/* - Copyright 2016 Chris Ballinger - Copyright 2016 OpenMarket Ltd - Copyright 2016 Vector Creations 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. - */ - -#import "OLMSession.h" -#import "OLMUtility.h" -#import "OLMAccount_Private.h" -#import "OLMSession_Private.h" -#include "olm/olm.h" - -@implementation OLMSession - -- (void) dealloc { - olm_clear_session(_session); - free(_session); -} - -- (BOOL) initializeSessionMemory { - size_t size = olm_session_size(); - _session = malloc(size); - NSParameterAssert(_session != nil); - if (!_session) { - return NO; - } - _session = olm_session(_session); - NSParameterAssert(_session != nil); - if (!_session) { - return NO; - } - return YES; -} - -- (instancetype) init { - self = [super init]; - if (!self) { - return nil; - } - BOOL success = [self initializeSessionMemory]; - if (!success) { - return nil; - } - return self; -} - -- (instancetype) initWithAccount:(OLMAccount*)account { - self = [self init]; - if (!self) { - return nil; - } - NSParameterAssert(account != nil && account.account != NULL); - if (account == nil || account.account == NULL) { - return nil; - } - _account = account; - return self; -} - -- (instancetype) initOutboundSessionWithAccount:(OLMAccount*)account theirIdentityKey:(NSString*)theirIdentityKey theirOneTimeKey:(NSString*)theirOneTimeKey error:(NSError**)error { - self = [self initWithAccount:account]; - if (!self) { - return nil; - } - NSMutableData *random = [OLMUtility randomBytesOfLength:olm_create_outbound_session_random_length(_session)]; - NSData *idKey = [theirIdentityKey dataUsingEncoding:NSUTF8StringEncoding]; - NSData *otKey = [theirOneTimeKey dataUsingEncoding:NSUTF8StringEncoding]; - size_t result = olm_create_outbound_session(_session, account.account, idKey.bytes, idKey.length, otKey.bytes, otKey.length, random.mutableBytes, random.length); - [random resetBytesInRange:NSMakeRange(0, random.length)]; - if (result == olm_error()) { - const char *olm_error = olm_session_last_error(_session); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - NSLog(@"olm_create_outbound_session error: %@", errorString); - - if (error && olm_error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_create_outbound_session error: %@", errorString] - }]; - } - - return nil; - } - return self; -} - -- (instancetype) initInboundSessionWithAccount:(OLMAccount*)account oneTimeKeyMessage:(NSString*)oneTimeKeyMessage error:(NSError**)error { - self = [self initWithAccount:account]; - if (!self) { - return nil; - } - NSMutableData *otk = [NSMutableData dataWithData:[oneTimeKeyMessage dataUsingEncoding:NSUTF8StringEncoding]]; - size_t result = olm_create_inbound_session(_session, account.account, otk.mutableBytes, oneTimeKeyMessage.length); - if (result == olm_error()) { - const char *olm_error = olm_session_last_error(_session); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - NSLog(@"olm_create_inbound_session error: %@", errorString); - - if (error && olm_error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_create_inbound_session error: %@", errorString] - }]; - } - - return nil; - } - return self; -} - -- (instancetype) initInboundSessionWithAccount:(OLMAccount*)account theirIdentityKey:(NSString*)theirIdentityKey oneTimeKeyMessage:(NSString*)oneTimeKeyMessage error:(NSError**)error { - self = [self initWithAccount:account]; - if (!self) { - return nil; - } - NSData *idKey = [theirIdentityKey dataUsingEncoding:NSUTF8StringEncoding]; - NSMutableData *otk = [NSMutableData dataWithData:[oneTimeKeyMessage dataUsingEncoding:NSUTF8StringEncoding]]; - size_t result = olm_create_inbound_session_from(_session, account.account, idKey.bytes, idKey.length, otk.mutableBytes, otk.length); - if (result == olm_error()) { - const char *olm_error = olm_session_last_error(_session); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - NSLog(@"olm_create_inbound_session_from error: %@", errorString); - - if (error && olm_error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_create_inbound_session_from error: %@", errorString] - }]; - } - - return nil; - } - return self; -} - -- (NSString*) sessionIdentifier { - size_t length = olm_session_id_length(_session); - NSMutableData *idData = [NSMutableData dataWithLength:length]; - if (!idData) { - return nil; - } - size_t result = olm_session_id(_session, idData.mutableBytes, idData.length); - if (result == olm_error()) { - const char *error = olm_session_last_error(_session); - NSLog(@"olm_session_id error: %s", error); - return nil; - } - NSString *idString = [[NSString alloc] initWithData:idData encoding:NSUTF8StringEncoding]; - return idString; -} - -- (BOOL)matchesInboundSession:(NSString *)oneTimeKeyMessage { - NSMutableData *otk = [NSMutableData dataWithData:[oneTimeKeyMessage dataUsingEncoding:NSUTF8StringEncoding]]; - - size_t result = olm_matches_inbound_session(_session, otk.mutableBytes, otk.length); - if (result == 1) { - return YES; - } - else { - if (result == olm_error()) { - const char *error = olm_session_last_error(_session); - NSLog(@"olm_matches_inbound_session error: %s", error); - } - return NO; - } -} - -- (BOOL)matchesInboundSessionFrom:(NSString *)theirIdentityKey oneTimeKeyMessage:(NSString *)oneTimeKeyMessage { - NSData *idKey = [theirIdentityKey dataUsingEncoding:NSUTF8StringEncoding]; - NSMutableData *otk = [NSMutableData dataWithData:[oneTimeKeyMessage dataUsingEncoding:NSUTF8StringEncoding]]; - - size_t result = olm_matches_inbound_session_from(_session, - idKey.bytes, idKey.length, - otk.mutableBytes, otk.length); - if (result == 1) { - return YES; - } - else { - if (result == olm_error()) { - const char *error = olm_session_last_error(_session); - NSLog(@"olm_matches_inbound_session error: %s", error); - } - return NO; - } -} - -- (OLMMessage*) encryptMessage:(NSString*)message error:(NSError**)error { - size_t messageType = olm_encrypt_message_type(_session); - size_t randomLength = olm_encrypt_random_length(_session); - NSMutableData *random = [OLMUtility randomBytesOfLength:randomLength]; - NSData *plaintextData = [message dataUsingEncoding:NSUTF8StringEncoding]; - size_t ciphertextLength = olm_encrypt_message_length(_session, plaintextData.length); - NSMutableData *ciphertext = [NSMutableData dataWithLength:ciphertextLength]; - if (!ciphertext) { - return nil; - } - size_t result = olm_encrypt(_session, plaintextData.bytes, plaintextData.length, random.mutableBytes, random.length, ciphertext.mutableBytes, ciphertext.length); - [random resetBytesInRange:NSMakeRange(0, random.length)]; - if (result == olm_error()) { - const char *olm_error = olm_session_last_error(_session); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - NSLog(@"olm_encrypt error: %@", errorString); - - if (error && olm_error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_encrypt error: %@", errorString] - }]; - } - - return nil; - } - NSString *ciphertextString = [[NSString alloc] initWithData:ciphertext encoding:NSUTF8StringEncoding]; - OLMMessage *encryptedMessage = [[OLMMessage alloc] initWithCiphertext:ciphertextString type:messageType]; - return encryptedMessage; -} - -- (NSString*) decryptMessage:(OLMMessage*)message error:(NSError**)error { - NSParameterAssert(message != nil); - NSData *messageData = [message.ciphertext dataUsingEncoding:NSUTF8StringEncoding]; - if (!messageData) { - return nil; - } - NSMutableData *mutMessage = messageData.mutableCopy; - size_t maxPlaintextLength = olm_decrypt_max_plaintext_length(_session, message.type, mutMessage.mutableBytes, mutMessage.length); - if (maxPlaintextLength == olm_error()) { - const char *olm_error = olm_session_last_error(_session); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - NSLog(@"olm_decrypt_max_plaintext_length error: %@", errorString); - - if (error && olm_error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_decrypt_max_plaintext_length error: %@", errorString] - }]; - } - - return nil; - } - // message buffer is destroyed by olm_decrypt_max_plaintext_length - mutMessage = messageData.mutableCopy; - NSMutableData *plaintextData = [NSMutableData dataWithLength:maxPlaintextLength]; - size_t plaintextLength = olm_decrypt(_session, message.type, mutMessage.mutableBytes, mutMessage.length, plaintextData.mutableBytes, plaintextData.length); - if (plaintextLength == olm_error()) { - const char *olm_error = olm_session_last_error(_session); - - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - NSLog(@"olm_decrypt error: %@", errorString); - - if (error && olm_error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain - code:0 - userInfo:@{ - NSLocalizedDescriptionKey: errorString, - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_decrypt error: %@", errorString] - }]; - } - - return nil; - } - plaintextData.length = plaintextLength; - NSString *plaintext = [[NSString alloc] initWithData:plaintextData encoding:NSUTF8StringEncoding]; - [plaintextData resetBytesInRange:NSMakeRange(0, plaintextData.length)]; - return plaintext; -} - -#pragma mark OLMSerializable - -/** Initializes from encrypted serialized data. Will throw error if invalid key or invalid base64. */ -- (instancetype) initWithSerializedData:(NSString*)serializedData key:(NSData*)key error:(NSError**)error { - self = [self init]; - if (!self) { - return nil; - } - NSParameterAssert(key.length > 0); - NSParameterAssert(serializedData.length > 0); - if (key.length == 0 || serializedData.length == 0) { - if (error) { - *error = [NSError errorWithDomain:OLMErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey: @"Bad length."}]; - } - return nil; - } - NSMutableData *pickle = [serializedData dataUsingEncoding:NSUTF8StringEncoding].mutableCopy; - size_t result = olm_unpickle_session(_session, key.bytes, key.length, pickle.mutableBytes, pickle.length); - [pickle resetBytesInRange:NSMakeRange(0, pickle.length)]; - if (result == olm_error()) { - const char *olm_error = olm_session_last_error(_session); - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - if (error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey: errorString}]; - } - return nil; - } - return self; -} - -/** Serializes and encrypts object data, outputs base64 blob */ -- (NSString*) serializeDataWithKey:(NSData*)key error:(NSError**)error { - NSParameterAssert(key.length > 0); - size_t length = olm_pickle_session_length(_session); - NSMutableData *pickled = [NSMutableData dataWithLength:length]; - size_t result = olm_pickle_session(_session, key.bytes, key.length, pickled.mutableBytes, pickled.length); - if (result == olm_error()) { - const char *olm_error = olm_session_last_error(_session); - NSString *errorString = [NSString stringWithUTF8String:olm_error]; - if (error && errorString) { - *error = [NSError errorWithDomain:OLMErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey: errorString}]; - } - return nil; - } - NSString *pickleString = [[NSString alloc] initWithData:pickled encoding:NSUTF8StringEncoding]; - [pickled resetBytesInRange:NSMakeRange(0, pickled.length)]; - return pickleString; -} - -#pragma mark NSSecureCoding - -+ (BOOL) supportsSecureCoding { - return YES; -} - -#pragma mark NSCoding - -- (id)initWithCoder:(NSCoder *)decoder { - NSString *version = [decoder decodeObjectOfClass:[NSString class] forKey:@"version"]; - - NSError *error = nil; - - if ([version isEqualToString:@"1"]) { - NSString *pickle = [decoder decodeObjectOfClass:[NSString class] forKey:@"pickle"]; - NSData *key = [decoder decodeObjectOfClass:[NSData class] forKey:@"key"]; - - self = [self initWithSerializedData:pickle key:key error:&error]; - } - - NSParameterAssert(error == nil); - NSParameterAssert(self != nil); - if (!self) { - return nil; - } - - return self; -} - -- (void)encodeWithCoder:(NSCoder *)encoder { - NSData *key = [OLMUtility randomBytesOfLength:32]; - NSError *error = nil; - NSString *pickle = [self serializeDataWithKey:key error:&error]; - NSParameterAssert(pickle.length > 0 && error == nil); - - [encoder encodeObject:pickle forKey:@"pickle"]; - [encoder encodeObject:key forKey:@"key"]; - [encoder encodeObject:@"1" forKey:@"version"]; -} - -@end diff --git a/xcode/OLMKit/OLMSession_Private.h b/xcode/OLMKit/OLMSession_Private.h deleted file mode 100644 index 28ba5e1..0000000 --- a/xcode/OLMKit/OLMSession_Private.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - Copyright 2016 Chris Ballinger - Copyright 2016 OpenMarket Ltd - Copyright 2016 Vector Creations 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. - */ - -#include "olm/olm.h" - -@interface OLMSession() - -@property (nonatomic) OlmSession *session; -@property (nonatomic, strong) OLMAccount *account; - -@end diff --git a/xcode/OLMKit/OLMUtility.h b/xcode/OLMKit/OLMUtility.h deleted file mode 100644 index 3041da9..0000000 --- a/xcode/OLMKit/OLMUtility.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - Copyright 2016 Chris Ballinger - Copyright 2016 OpenMarket Ltd - Copyright 2016 Vector Creations 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. - */ - -#import <Foundation/Foundation.h> - -FOUNDATION_EXPORT NSString *const OLMErrorDomain; - -@interface OLMUtility : NSObject - -/** - Calculate the SHA-256 hash of the input and encodes it as base64. - - @param message the message to hash. - @return the base64-encoded hash value. - */ -- (NSString*)sha256:(NSData*)message; - -/** - Verify an ed25519 signature. - - @param signature the base64-encoded signature to be checked. - @param key the ed25519 key. - @param message the message which was signed. - @param error if there is a problem with the verification. - If the key was too small then the message will be "OLM.INVALID_BASE64". - If the signature was invalid then the message will be "OLM.BAD_MESSAGE_MAC". - - @return YES if valid. - */ -- (BOOL)verifyEd25519Signature:(NSString*)signature key:(NSString*)key message:(NSData*)message error:(NSError**)error; - -+ (NSMutableData*) randomBytesOfLength:(NSUInteger)length; - -@end diff --git a/xcode/OLMKit/OLMUtility.m b/xcode/OLMKit/OLMUtility.m deleted file mode 100644 index 936785a..0000000 --- a/xcode/OLMKit/OLMUtility.m +++ /dev/null @@ -1,121 +0,0 @@ -/* - Copyright 2016 Chris Ballinger - Copyright 2016 OpenMarket Ltd - Copyright 2016 Vector Creations 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. - */ - -#import "OLMUtility.h" - -#include "olm/olm.h" - -NSString *const OLMErrorDomain = @"org.matrix.olm"; - -@interface OLMUtility() - -@property (nonatomic) OlmUtility *utility; - -@end - -@implementation OLMUtility - -- (void) dealloc { - olm_clear_utility(_utility); - free(_utility); -} - -- (BOOL) initializeUtilityMemory { - size_t utilitySize = olm_utility_size(); - _utility = malloc(utilitySize); - NSParameterAssert(_utility != nil); - if (!_utility) { - return NO; - } - _utility = olm_utility(_utility); - NSParameterAssert(_utility != nil); - if (!_utility) { - return NO; - } - return YES; -} - -- (instancetype) init { - self = [super init]; - if (!self) { - return nil; - } - BOOL success = [self initializeUtilityMemory]; - if (!success) { - return nil; - } - return self; -} - -- (NSString *)sha256:(NSData *)message { - size_t length = olm_sha256_length(_utility); - - NSMutableData *shaData = [NSMutableData dataWithLength:length]; - if (!shaData) { - return nil; - } - - size_t result = olm_sha256(_utility, message.bytes, message.length, shaData.mutableBytes, shaData.length); - if (result == olm_error()) { - const char *error = olm_utility_last_error(_utility); - NSLog(@"olm_sha256 error: %s", error); - return nil; - } - - NSString *sha = [[NSString alloc] initWithData:shaData encoding:NSUTF8StringEncoding]; - return sha; -} - -- (BOOL)verifyEd25519Signature:(NSString*)signature key:(NSString*)key message:(NSData*)message error:(NSError**)error { - - NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding]; - NSData *signatureData = [signature dataUsingEncoding:NSUTF8StringEncoding]; - - size_t result = olm_ed25519_verify(_utility, - keyData.bytes, keyData.length, - message.bytes, message.length, - (void*)signatureData.bytes, signatureData.length - ); - - if (result == olm_error()) { - if (error) { - NSDictionary *userInfo = @{NSLocalizedFailureReasonErrorKey: [NSString stringWithUTF8String:olm_utility_last_error(_utility)]}; - - // @TODO - *error = [[NSError alloc] initWithDomain:@"OLMKitErrorDomain" code:0 userInfo:userInfo]; - } - return NO; - } - else { - return YES; - } -} - -+ (NSMutableData*) randomBytesOfLength:(NSUInteger)length { - NSMutableData *randomData = [NSMutableData dataWithLength:length]; - if (!randomData) { - return nil; - } - int result = SecRandomCopyBytes(kSecRandomDefault, randomData.length, randomData.mutableBytes); - if (result != 0) { - return nil; - } - return randomData; -} - -@end diff --git a/xcode/OLMKitTests/Info.plist b/xcode/OLMKitTests/Info.plist deleted file mode 100644 index 6c6c23c..0000000 --- a/xcode/OLMKitTests/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>en</string> - <key>CFBundleExecutable</key> - <string>$(EXECUTABLE_NAME)</string> - <key>CFBundleIdentifier</key> - <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>$(PRODUCT_NAME)</string> - <key>CFBundlePackageType</key> - <string>BNDL</string> - <key>CFBundleShortVersionString</key> - <string>1.0</string> - <key>CFBundleVersion</key> - <string>1</string> -</dict> -</plist> diff --git a/xcode/OLMKitTests/OLMKitGroupTests.m b/xcode/OLMKitTests/OLMKitGroupTests.m deleted file mode 100644 index 39ad400..0000000 --- a/xcode/OLMKitTests/OLMKitGroupTests.m +++ /dev/null @@ -1,146 +0,0 @@ -/* - Copyright 2016 OpenMarket Ltd - Copyright 2016 Vector Creations 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. - */ - -#import <XCTest/XCTest.h> - -#import <OLMKit/OLMKit.h> - -#include "olm/olm.h" - -@interface OLMKitGroupTests : XCTestCase - -@end - -@implementation OLMKitGroupTests - -- (void)setUp { - [super setUp]; - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. - [super tearDown]; -} - -- (void)testAliceAndBob { - NSError *error; - - OLMOutboundGroupSession *aliceSession = [[OLMOutboundGroupSession alloc] initOutboundGroupSession]; - XCTAssertGreaterThan(aliceSession.sessionIdentifier.length, 0); - XCTAssertGreaterThan(aliceSession.sessionKey.length, 0); - XCTAssertEqual(aliceSession.messageIndex, 0); - - // Store the session key before starting encrypting - NSString *sessionKey = aliceSession.sessionKey; - - NSString *message = @"Hello!"; - NSString *aliceToBobMsg = [aliceSession encryptMessage:message error:&error]; - - XCTAssertEqual(aliceSession.messageIndex, 1); - XCTAssertGreaterThanOrEqual(aliceToBobMsg.length, 0); - XCTAssertNil(error); - - OLMInboundGroupSession *bobSession = [[OLMInboundGroupSession alloc] initInboundGroupSessionWithSessionKey:sessionKey error:&error]; - XCTAssertEqualObjects(aliceSession.sessionIdentifier, bobSession.sessionIdentifier); - XCTAssertNil(error); - - NSUInteger messageIndex; - - NSString *plaintext = [bobSession decryptMessage:aliceToBobMsg messageIndex:&messageIndex error:&error]; - XCTAssertEqualObjects(message, plaintext); - - XCTAssertEqual(messageIndex, 0); - XCTAssertNil(error); -} - -- (void)testOutboundGroupSessionSerialization { - - OLMOutboundGroupSession *aliceSession = [[OLMOutboundGroupSession alloc] initOutboundGroupSession]; - - NSData *aliceData = [NSKeyedArchiver archivedDataWithRootObject:aliceSession]; - OLMOutboundGroupSession *aliceSession2 = [NSKeyedUnarchiver unarchiveObjectWithData:aliceData]; - - XCTAssertEqualObjects(aliceSession2.sessionKey, aliceSession.sessionKey); - XCTAssertEqualObjects(aliceSession2.sessionIdentifier, aliceSession.sessionIdentifier); -} - -- (void)testInboundGroupSessionSerialization { - - OLMOutboundGroupSession *aliceSession = [[OLMOutboundGroupSession alloc] initOutboundGroupSession]; - - OLMInboundGroupSession *bobSession = [[OLMInboundGroupSession alloc] initInboundGroupSessionWithSessionKey:aliceSession.sessionKey error:nil]; - - NSData *bobData = [NSKeyedArchiver archivedDataWithRootObject:bobSession]; - OLMInboundGroupSession *bobSession2 = [NSKeyedUnarchiver unarchiveObjectWithData:bobData]; - - XCTAssertEqualObjects(bobSession2.sessionIdentifier, aliceSession.sessionIdentifier); -} - -- (void)testInboundGroupSessionImportExport { - - NSError *error; - - NSString *sessionKey = @"AgAAAAAwMTIzNDU2Nzg5QUJERUYwMTIzNDU2Nzg5QUJDREVGMDEyMzQ1Njc4OUFCREVGM" \ - "DEyMzQ1Njc4OUFCQ0RFRjAxMjM0NTY3ODlBQkRFRjAxMjM0NTY3ODlBQkNERUYwMTIzND" \ - "U2Nzg5QUJERUYwMTIzNDU2Nzg5QUJDREVGMDEyMw0bdg1BDq4Px/slBow06q8n/B9WBfw" \ - "WYyNOB8DlUmXGGwrFmaSb9bR/eY8xgERrxmP07hFmD9uqA2p8PMHdnV5ysmgufE6oLZ5+" \ - "8/mWQOW3VVTnDIlnwd8oHUYRuk8TCQ"; - - NSString *message = @"AwgAEhAcbh6UpbByoyZxufQ+h2B+8XHMjhR69G8F4+qjMaFlnIXusJZX3r8LnRORG9T3D" \ - "XFdbVuvIWrLyRfm4i8QRbe8VPwGRFG57B1CtmxanuP8bHtnnYqlwPsD"; - - // init first inbound group session, and decrypt */ - OLMInboundGroupSession *session1 = [[OLMInboundGroupSession alloc] initInboundGroupSessionWithSessionKey:sessionKey error:&error]; - - XCTAssertNil(error); - XCTAssertTrue(session1.isVerified); - - // decrypt the message - NSUInteger messageIndex; - NSString *plaintext = [session1 decryptMessage:message messageIndex:&messageIndex error:&error]; - - XCTAssertNil(error); - XCTAssertEqualObjects(plaintext, @"Message"); - XCTAssertEqual(messageIndex, 0); - - // export the keys - NSString *export = [session1 exportSessionAtMessageIndex:0 error:&error]; - - XCTAssertNil(error); - XCTAssertGreaterThan(export.length, 0); - - // free the old session to check there is no shared data - session1 = nil; - - // import the keys into another inbound group session - OLMInboundGroupSession *session2 = [[OLMInboundGroupSession alloc] initInboundGroupSessionWithImportedSession:export error:&error]; - - XCTAssertNil(error); - XCTAssert(session2); - XCTAssertFalse(session2.isVerified); - - // decrypt the message with the new session - NSString *plaintext2 = [session2 decryptMessage:message messageIndex:&messageIndex error:&error]; - - XCTAssertNil(error); - XCTAssertEqualObjects(plaintext2, @"Message"); - XCTAssertEqual(messageIndex, 0); - XCTAssertTrue(session2.isVerified); -} - -@end diff --git a/xcode/OLMKitTests/OLMKitPkTests.m b/xcode/OLMKitTests/OLMKitPkTests.m deleted file mode 100644 index 7a09130..0000000 --- a/xcode/OLMKitTests/OLMKitPkTests.m +++ /dev/null @@ -1,142 +0,0 @@ -/* - Copyright 2018 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. - */ - -#import <XCTest/XCTest.h> -#import <OLMKit/OLMKit.h> - -/** - Tests are inspired from js tests. - */ -@interface OLMKitPkTests : XCTestCase { - OLMPkEncryption *encryption; - OLMPkDecryption *decryption; -} - -@end - -@implementation OLMKitPkTests - -- (void)setUp { - encryption = [OLMPkEncryption new]; - decryption = [OLMPkDecryption new]; -} - -- (void)tearDown { - encryption = nil; - decryption = nil; -} - -- (void)testImportExportKeys { - UInt8 alicePrivateBytes[] = { - 0x77, 0x07, 0x6D, 0x0A, 0x73, 0x18, 0xA5, 0x7D, - 0x3C, 0x16, 0xC1, 0x72, 0x51, 0xB2, 0x66, 0x45, - 0xDF, 0x4C, 0x2F, 0x87, 0xEB, 0xC0, 0x99, 0x2A, - 0xB1, 0x77, 0xFB, 0xA5, 0x1D, 0xB9, 0x2C, 0x2A - }; - - NSData *alicePrivate = [NSData dataWithBytes:alicePrivateBytes length:sizeof(alicePrivateBytes)]; - - NSError *error; - NSString *alicePublic = [decryption setPrivateKey:alicePrivate error:&error]; - XCTAssertNil(error); - XCTAssertEqualObjects(alicePublic, @"hSDwCYkwp1R0i33ctD73Wg2/Og0mOBr066SpjqqbTmo"); - - NSData *alicePrivateOut = decryption.privateKey; - XCTAssertNil(error); - XCTAssertEqualObjects(alicePrivateOut, alicePrivate); -} - -- (void)testEncryptAndDecrypt { - - NSString *pubKey = [decryption generateKey:nil]; - NSLog(@"Ephemeral Key: %@", pubKey); - XCTAssertNotNil(pubKey); - - NSString *TEST_TEXT = @"têst1"; - NSError *error; - [encryption setRecipientKey:pubKey]; - OLMPkMessage *message = [encryption encryptMessage:TEST_TEXT error:&error]; - NSLog(@"message: %@ %@ %@", message.ciphertext, message.mac, message.ephemeralKey); - XCTAssertNil(error); - XCTAssertNotNil(message); - XCTAssertNotNil(message.ciphertext); - XCTAssertNotNil(message.mac); - XCTAssertNotNil(message.ephemeralKey); - - NSString *decrypted = [decryption decryptMessage:message error:&error]; - XCTAssertNil(error); - XCTAssertEqualObjects(decrypted, TEST_TEXT); - - TEST_TEXT = @"hot beverage: ☕"; - [encryption setRecipientKey:pubKey]; - message = [encryption encryptMessage:TEST_TEXT error:&error]; - decrypted = [decryption decryptMessage:message error:&error]; - XCTAssertEqualObjects(decrypted, TEST_TEXT); -} - -- (void)testOLMPkDecryptionSerialization { - NSString *TEST_TEXT = @"têst1"; - NSString *pubKey = [decryption generateKey:nil]; - [encryption setRecipientKey:pubKey]; - OLMPkMessage *encrypted = [encryption encryptMessage:TEST_TEXT error:nil]; - - - NSData *pickle = [NSKeyedArchiver archivedDataWithRootObject:decryption]; - decryption = nil; - - OLMPkDecryption *newDecryption = [NSKeyedUnarchiver unarchiveObjectWithData:pickle]; - - NSError *error; - NSString *decrypted = [newDecryption decryptMessage:encrypted error:&error]; - XCTAssertEqualObjects(decrypted, TEST_TEXT); -} - -- (void)testSignAndVerify { - - UInt8 seedBytes[] = { - 0x77, 0x07, 0x6D, 0x0A, 0x73, 0x18, 0xA5, 0x7D, - 0x3C, 0x16, 0xC1, 0x72, 0x51, 0xB2, 0x66, 0x45, - 0xDF, 0x4C, 0x2F, 0x87, 0xEB, 0xC0, 0x99, 0x2A, - 0xB1, 0x77, 0xFB, 0xA5, 0x1D, 0xB9, 0x2C, 0x2A - }; - - NSData *seed = [NSData dataWithBytes:seedBytes length:sizeof(seedBytes)]; - - NSString *TEST_TEXT = @"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."; - - OLMPkSigning *signing = [OLMPkSigning new]; - - NSError *error; - NSString *pubKey = [signing doInitWithSeed:seed error:&error]; - XCTAssertNotNil(pubKey); - XCTAssertNil(error); - - NSString *sig = [signing sign:TEST_TEXT error:&error]; - XCTAssertNotNil(sig); - XCTAssertNil(error); - - OLMUtility *util = [OLMUtility new]; - BOOL verify = [util verifyEd25519Signature:sig key:pubKey message:[TEST_TEXT dataUsingEncoding:NSUTF8StringEncoding] error:&error]; - XCTAssertTrue(verify); - XCTAssertNil(error); - - NSString *badSig = [sig stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:@"p"]; - verify = [util verifyEd25519Signature:badSig key:pubKey message:[TEST_TEXT dataUsingEncoding:NSUTF8StringEncoding] error:&error]; - XCTAssertFalse(verify); - XCTAssertNotNil(error); -} - -@end diff --git a/xcode/OLMKitTests/OLMKitSASTests.m b/xcode/OLMKitTests/OLMKitSASTests.m deleted file mode 100644 index e250a67..0000000 --- a/xcode/OLMKitTests/OLMKitSASTests.m +++ /dev/null @@ -1,86 +0,0 @@ -/* - Copyright 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. - */ - -#import <XCTest/XCTest.h> -#import <OLMKit/OLMKit.h> - -@interface OLMKitSASTests : XCTestCase { - OLMSAS *alice; - OLMSAS *bob; -} - -@end - -@implementation OLMKitSASTests - -- (void)setUp { - alice = [OLMSAS new]; - bob = [OLMSAS new]; -} - -- (void)tearDown { - alice = nil; - bob = nil; -} - -- (void)testSASRandomness -{ - XCTAssertNotEqualObjects(alice.publicKey, bob.publicKey); -} - -- (void)testSASBytesMatch { - [alice setTheirPublicKey:bob.publicKey]; - [bob setTheirPublicKey:alice.publicKey]; - - NSString *sas = @"SAS"; - NSUInteger length = 5; - - XCTAssertEqualObjects([alice generateBytes:sas length:length], - [bob generateBytes:sas length:length]); -} - -- (void)testMACsMatch { - [alice setTheirPublicKey:bob.publicKey]; - [bob setTheirPublicKey:alice.publicKey]; - - NSString *string = @"test"; - NSString *info = @"MAC"; - - NSError *aliceError, *bobError; - XCTAssertEqualObjects([alice calculateMac:string info:info error:&aliceError], - [bob calculateMac:string info:info error:&bobError]); - XCTAssertNil(aliceError); - XCTAssertNil(bobError); -} - -- (void)testMACLongKdfsMatch { - [alice setTheirPublicKey:bob.publicKey]; - [bob setTheirPublicKey:alice.publicKey]; - - NSString *string = @"test"; - NSString *info = @"MAC"; - - NSError *aliceError, *bobError; - XCTAssertEqualObjects([alice calculateMacLongKdf:string info:info error:&aliceError], - [bob calculateMacLongKdf:string info:info error:&bobError]); - XCTAssertNotEqualObjects([alice calculateMacLongKdf:string info:info error:&aliceError], - [bob calculateMac:string info:info error:&bobError]); - XCTAssertNil(aliceError); - XCTAssertNil(bobError); -} - - -@end diff --git a/xcode/OLMKitTests/OLMKitTests.m b/xcode/OLMKitTests/OLMKitTests.m deleted file mode 100644 index ee02420..0000000 --- a/xcode/OLMKitTests/OLMKitTests.m +++ /dev/null @@ -1,206 +0,0 @@ -/* -Copyright 2016 Chris Ballinger -Copyright 2016 OpenMarket Ltd -Copyright 2016 Vector Creations 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. -*/ - -#import <XCTest/XCTest.h> -#import <OLMKit/OLMKit.h> - -@interface OLMKitTests : XCTestCase - -@end - -@implementation OLMKitTests - -- (void)setUp { - [super setUp]; - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. - [super tearDown]; -} - -- (void)testAliceAndBob { - NSError *error; - - OLMAccount *alice = [[OLMAccount alloc] initNewAccount]; - OLMAccount *bob = [[OLMAccount alloc] initNewAccount]; - [bob generateOneTimeKeys:5]; - NSDictionary *bobIdKeys = bob.identityKeys; - NSString *bobIdKey = bobIdKeys[@"curve25519"]; - NSDictionary *bobOneTimeKeys = bob.oneTimeKeys; - NSParameterAssert(bobIdKey != nil); - NSParameterAssert(bobOneTimeKeys != nil); - __block NSString *bobOneTimeKey = nil; - NSDictionary *bobOtkCurve25519 = bobOneTimeKeys[@"curve25519"]; - [bobOtkCurve25519 enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { - bobOneTimeKey = obj; - }]; - XCTAssert([bobOneTimeKey isKindOfClass:[NSString class]]); - - OLMSession *aliceSession = [[OLMSession alloc] initOutboundSessionWithAccount:alice theirIdentityKey:bobIdKey theirOneTimeKey:bobOneTimeKey error:nil]; - NSString *message = @"Hello!"; - OLMMessage *aliceToBobMsg = [aliceSession encryptMessage:message error:&error]; - XCTAssertNil(error); - - OLMSession *bobSession = [[OLMSession alloc] initInboundSessionWithAccount:bob oneTimeKeyMessage:aliceToBobMsg.ciphertext error:nil]; - NSString *plaintext = [bobSession decryptMessage:aliceToBobMsg error:&error]; - XCTAssertEqualObjects(message, plaintext); - XCTAssertNil(error); - - XCTAssert([bobSession matchesInboundSession:aliceToBobMsg.ciphertext]); - XCTAssertFalse([aliceSession matchesInboundSession:@"ARandomOtkMessage"]); - - NSString *aliceIdKey = alice.identityKeys[@"curve25519"]; - XCTAssert([bobSession matchesInboundSessionFrom:aliceIdKey oneTimeKeyMessage:aliceToBobMsg.ciphertext]); - XCTAssertFalse([bobSession matchesInboundSessionFrom:@"ARandomIdKey" oneTimeKeyMessage:aliceToBobMsg.ciphertext]); - XCTAssertFalse([bobSession matchesInboundSessionFrom:aliceIdKey oneTimeKeyMessage:@"ARandomOtkMessage"]); - - BOOL success = [bob removeOneTimeKeysForSession:bobSession]; - XCTAssertTrue(success); -} - -- (void) testBackAndForth { - OLMAccount *alice = [[OLMAccount alloc] initNewAccount]; - OLMAccount *bob = [[OLMAccount alloc] initNewAccount]; - [bob generateOneTimeKeys:1]; - NSDictionary *bobIdKeys = bob.identityKeys; - NSString *bobIdKey = bobIdKeys[@"curve25519"]; - NSDictionary *bobOneTimeKeys = bob.oneTimeKeys; - NSParameterAssert(bobIdKey != nil); - NSParameterAssert(bobOneTimeKeys != nil); - __block NSString *bobOneTimeKey = nil; - NSDictionary *bobOtkCurve25519 = bobOneTimeKeys[@"curve25519"]; - [bobOtkCurve25519 enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { - bobOneTimeKey = obj; - }]; - XCTAssert([bobOneTimeKey isKindOfClass:[NSString class]]); - - OLMSession *aliceSession = [[OLMSession alloc] initOutboundSessionWithAccount:alice theirIdentityKey:bobIdKey theirOneTimeKey:bobOneTimeKey error:nil]; - NSString *message = @"Hello I'm Alice!"; - OLMMessage *aliceToBobMsg = [aliceSession encryptMessage:message error:nil]; - - OLMSession *bobSession = [[OLMSession alloc] initInboundSessionWithAccount:bob oneTimeKeyMessage:aliceToBobMsg.ciphertext error:nil]; - NSString *plaintext = [bobSession decryptMessage:aliceToBobMsg error:nil]; - XCTAssertEqualObjects(message, plaintext); - BOOL success = [bob removeOneTimeKeysForSession:bobSession]; - XCTAssertTrue(success); - - NSString *msg1 = @"Hello I'm Bob!"; - NSString *msg2 = @"Isn't life grand?"; - NSString *msg3 = @"Let's go to the opera."; - - OLMMessage *eMsg1 = [bobSession encryptMessage:msg1 error:nil]; - OLMMessage *eMsg2 = [bobSession encryptMessage:msg2 error:nil]; - OLMMessage *eMsg3 = [bobSession encryptMessage:msg3 error:nil]; - - NSString *dMsg1 = [aliceSession decryptMessage:eMsg1 error:nil]; - NSString *dMsg2 = [aliceSession decryptMessage:eMsg2 error:nil]; - NSString *dMsg3 = [aliceSession decryptMessage:eMsg3 error:nil]; - XCTAssertEqualObjects(msg1, dMsg1); - XCTAssertEqualObjects(msg2, dMsg2); - XCTAssertEqualObjects(msg3, dMsg3); -} - -- (void) testAccountSerialization { - OLMAccount *bob = [[OLMAccount alloc] initNewAccount]; - [bob generateOneTimeKeys:5]; - NSDictionary *bobIdKeys = bob.identityKeys; - NSDictionary *bobOneTimeKeys = bob.oneTimeKeys; - - NSData *bobData = [NSKeyedArchiver archivedDataWithRootObject:bob]; - - OLMAccount *bob2 = [NSKeyedUnarchiver unarchiveObjectWithData:bobData]; - NSDictionary *bobIdKeys2 = bob2.identityKeys; - NSDictionary *bobOneTimeKeys2 = bob2.oneTimeKeys; - - XCTAssertEqualObjects(bobIdKeys, bobIdKeys2); - XCTAssertEqualObjects(bobOneTimeKeys, bobOneTimeKeys2); -} - -- (void) testSessionSerialization { - NSError *error; - - OLMAccount *alice = [[OLMAccount alloc] initNewAccount]; - OLMAccount *bob = [[OLMAccount alloc] initNewAccount]; - [bob generateOneTimeKeys:1]; - NSDictionary *bobIdKeys = bob.identityKeys; - NSString *bobIdKey = bobIdKeys[@"curve25519"]; - NSDictionary *bobOneTimeKeys = bob.oneTimeKeys; - NSParameterAssert(bobIdKey != nil); - NSParameterAssert(bobOneTimeKeys != nil); - __block NSString *bobOneTimeKey = nil; - NSDictionary *bobOtkCurve25519 = bobOneTimeKeys[@"curve25519"]; - [bobOtkCurve25519 enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { - bobOneTimeKey = obj; - }]; - XCTAssert([bobOneTimeKey isKindOfClass:[NSString class]]); - - OLMSession *aliceSession = [[OLMSession alloc] initOutboundSessionWithAccount:alice theirIdentityKey:bobIdKey theirOneTimeKey:bobOneTimeKey error:nil]; - NSString *message = @"Hello I'm Alice!"; - OLMMessage *aliceToBobMsg = [aliceSession encryptMessage:message error:&error]; - XCTAssertNil(error); - - - OLMSession *bobSession = [[OLMSession alloc] initInboundSessionWithAccount:bob oneTimeKeyMessage:aliceToBobMsg.ciphertext error:nil]; - NSString *plaintext = [bobSession decryptMessage:aliceToBobMsg error:nil]; - XCTAssertEqualObjects(message, plaintext); - BOOL success = [bob removeOneTimeKeysForSession:bobSession]; - XCTAssertTrue(success); - - NSString *msg1 = @"Hello I'm Bob!"; - NSString *msg2 = @"Isn't life grand?"; - NSString *msg3 = @"Let's go to the opera."; - - OLMMessage *eMsg1 = [bobSession encryptMessage:msg1 error:nil]; - OLMMessage *eMsg2 = [bobSession encryptMessage:msg2 error:nil]; - OLMMessage *eMsg3 = [bobSession encryptMessage:msg3 error:nil]; - - NSData *aliceData = [NSKeyedArchiver archivedDataWithRootObject:aliceSession]; - OLMSession *alice2 = [NSKeyedUnarchiver unarchiveObjectWithData:aliceData]; - - NSString *dMsg1 = [alice2 decryptMessage:eMsg1 error:nil]; - NSString *dMsg2 = [alice2 decryptMessage:eMsg2 error:nil]; - NSString *dMsg3 = [alice2 decryptMessage:eMsg3 error:nil]; - XCTAssertEqualObjects(msg1, dMsg1); - XCTAssertEqualObjects(msg2, dMsg2); - XCTAssertEqualObjects(msg3, dMsg3); -} - -- (void)testEd25519Signing { - - OLMUtility *olmUtility = [[OLMUtility alloc] init]; - OLMAccount *alice = [[OLMAccount alloc] initNewAccount]; - - NSDictionary *aJSON = @{ - @"key1": @"value1", - @"key2": @"value2" - }; - NSData *message = [NSKeyedArchiver archivedDataWithRootObject:aJSON]; - NSString *signature = [alice signMessage:message]; - - - NSString *aliceEd25519Key = alice.identityKeys[@"ed25519"]; - - NSError *error; - BOOL result = [olmUtility verifyEd25519Signature:signature key:aliceEd25519Key message:message error:&error]; - XCTAssert(result); - XCTAssertNil(error); -} - -@end diff --git a/xcode/Podfile b/xcode/Podfile deleted file mode 100644 index 4c60dd3..0000000 --- a/xcode/Podfile +++ /dev/null @@ -1,7 +0,0 @@ -target "OLMKit" do -pod 'OLMKit', :path => '../OLMKit.podspec' -end - -target "OLMKitTests" do -pod 'OLMKit', :path => '../OLMKit.podspec' -end
\ No newline at end of file diff --git a/xcode/Podfile.lock b/xcode/Podfile.lock deleted file mode 100644 index e6f2333..0000000 --- a/xcode/Podfile.lock +++ /dev/null @@ -1,20 +0,0 @@ -PODS: - - OLMKit (3.1.0): - - OLMKit/olmc (= 3.1.0) - - OLMKit/olmcpp (= 3.1.0) - - OLMKit/olmc (3.1.0) - - OLMKit/olmcpp (3.1.0) - -DEPENDENCIES: - - OLMKit (from `../OLMKit.podspec`) - -EXTERNAL SOURCES: - OLMKit: - :path: "../OLMKit.podspec" - -SPEC CHECKSUMS: - OLMKit: c806e1d2295c8aa1e19de66f4f470c4472d23ba1 - -PODFILE CHECKSUM: 4e261dae61d833ec5585ced2473023b98909fd35 - -COCOAPODS: 1.6.1 diff --git a/xcode/README.rst b/xcode/README.rst deleted file mode 100644 index d56fa85..0000000 --- a/xcode/README.rst +++ /dev/null @@ -1,26 +0,0 @@ -OLMKit -====== - -OLMKit exposes an Objective-C wrapper to libolm. - -The original work by Chris Ballinger can be found at https://github.com/chrisballinger/OLMKit. - -Installation ------------- -You can embed OLMKit to your application project with CocoaPods. The pod for -the latest OLMKit release is:: - - pod 'OLMKit' - -Development ------------ -Run `pod install` and open `OLMKit.xcworkspace`. - -The project contains only tests files. The libolm and the Objective-C wrapper source files are loaded via the OLMKit CocoaPods pod. - -To add a new source file, add it to the file system and run `pod update` to make CocoaPods insert it into OLMKit.xcworkspace. - -Release -------- -See ../README.rst for the release of the CocoaPod. - |