From 7c22f15dcda519ed027ef50af6f1448111f81267 Mon Sep 17 00:00:00 2001 From: Toralf Wittner Date: Fri, 6 Nov 2015 21:11:18 +0100 Subject: [PATCH] Remove cryptobox-c which got its own repository. --- .gitignore | 1 - .travis.yml | 14 +- cryptobox/Cargo.toml => Cargo.toml | 0 cryptobox-c/LICENSE => LICENSE | 0 README.md | 14 +- cryptobox-c/Cargo.lock | 86 ------ cryptobox-c/Cargo.toml | 22 -- cryptobox-c/Makefile | 68 ----- cryptobox-c/README.md | 116 -------- cryptobox-c/deb/DEBIAN/control | 6 - cryptobox-c/deb/DEBIAN/postinst | 4 - cryptobox-c/deb/DEBIAN/prerm | 4 - cryptobox-c/src/cbox.h | 294 ------------------- cryptobox-c/src/lib.rs | 307 -------------------- cryptobox-c/src/log.rs | 54 ---- cryptobox-c/test/bench.c | 86 ------ cryptobox-c/test/main.c | 406 --------------------------- cryptobox/LICENSE | 373 ------------------------ {cryptobox/src => src}/identity.rs | 0 {cryptobox/src => src}/lib.rs | 0 {cryptobox/src => src}/store/file.rs | 0 {cryptobox/src => src}/store/mod.rs | 0 22 files changed, 11 insertions(+), 1844 deletions(-) rename cryptobox/Cargo.toml => Cargo.toml (100%) rename cryptobox-c/LICENSE => LICENSE (100%) delete mode 100644 cryptobox-c/Cargo.lock delete mode 100644 cryptobox-c/Cargo.toml delete mode 100644 cryptobox-c/Makefile delete mode 100644 cryptobox-c/README.md delete mode 100644 cryptobox-c/deb/DEBIAN/control delete mode 100755 cryptobox-c/deb/DEBIAN/postinst delete mode 100755 cryptobox-c/deb/DEBIAN/prerm delete mode 100644 cryptobox-c/src/cbox.h delete mode 100644 cryptobox-c/src/lib.rs delete mode 100644 cryptobox-c/src/log.rs delete mode 100644 cryptobox-c/test/bench.c delete mode 100644 cryptobox-c/test/main.c delete mode 100644 cryptobox/LICENSE rename {cryptobox/src => src}/identity.rs (100%) rename {cryptobox/src => src}/lib.rs (100%) rename {cryptobox/src => src}/store/file.rs (100%) rename {cryptobox/src => src}/store/mod.rs (100%) diff --git a/.gitignore b/.gitignore index 8ae6865..8dda546 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ target test/target Cargo.lock -!cryptobox-c/Cargo.lock *.swp *.swo tags diff --git a/.travis.yml b/.travis.yml index 0d32af9..e1f6706 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,7 @@ language: rust rust: nightly -before_install: - - sudo apt-get update -qq - -install: - - sudo apt-get install -y valgrind - - wget "https://github.com/jedisct1/libsodium/releases/download/1.0.3/libsodium-1.0.3.tar.gz" - - tar -xzf libsodium-1.0.3.tar.gz - - cd libsodium-1.0.3 && ./configure --prefix=/usr && make && sudo make install && cd .. - -script: cd cryptobox-c && make test +before_script: + - wget "https://github.com/jedisct1/libsodium/releases/download/1.0.6/libsodium-1.0.6.tar.gz" + - tar -xzvf libsodium-1.0.6.tar.gz + - cd libsodium-1.0.6 && ./configure --prefix=/usr && make && sudo make install diff --git a/cryptobox/Cargo.toml b/Cargo.toml similarity index 100% rename from cryptobox/Cargo.toml rename to Cargo.toml diff --git a/cryptobox-c/LICENSE b/LICENSE similarity index 100% rename from cryptobox-c/LICENSE rename to LICENSE diff --git a/README.md b/README.md index 1c1886c..5b12339 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# Cryptobox [![Build Status](https://travis-ci.org/shared-secret/cryptobox.svg?branch=develop)](https://travis-ci.org/shared-secret/cryptobox) +# Cryptobox -`Cryptobox` provides a high-level API with persistent storage for the -[proteus](https://github.com/shared-secret/proteus) implementation of the -[axolotl](https://github.com/trevp/axolotl/wiki) protocol. +[![Build Status](https://travis-ci.org/shared-secret/cryptobox.svg?branch=develop)][1] -## Modules +Cryptobox provides a high-level API with persistent storage for the +[proteus][2] implementation of the [axolotl][3] protocol. - * [cryptobox](cryptobox): Rust API - * [cryptobox-c](cryptobox-c/README.md): C API +[1]: https://travis-ci.org/shared-secret/cryptobox +[2]: https://github.com/shared-secret/proteus +[3]: https://github.com/trevp/axolotl/wiki diff --git a/cryptobox-c/Cargo.lock b/cryptobox-c/Cargo.lock deleted file mode 100644 index edc1f20..0000000 --- a/cryptobox-c/Cargo.lock +++ /dev/null @@ -1,86 +0,0 @@ -[root] -name = "cryptobox-c" -version = "0.5.1" -dependencies = [ - "cryptobox 0.5.1", - "libc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proteus 0.4.1 (git+https://github.com/shared-secret/proteus?branch=develop)", -] - -[[package]] -name = "byteorder" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "cbor-codec" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cryptobox" -version = "0.5.1" -dependencies = [ - "byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", - "cbor-codec 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "proteus 0.4.1 (git+https://github.com/shared-secret/proteus?branch=develop)", -] - -[[package]] -name = "hkdf" -version = "0.1.0" -source = "git+https://github.com/twittner/hkdf#e4a0760b0a50ddcd12fc92eb6443db613108b845" -dependencies = [ - "sodiumoxide 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libc" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "libsodium-sys" -version = "0.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "pkg-config" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "proteus" -version = "0.4.1" -source = "git+https://github.com/shared-secret/proteus?branch=develop#aaabc38cb446cb1c36d749557a13e27e7094cde9" -dependencies = [ - "byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", - "cbor-codec 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hkdf 0.1.0 (git+https://github.com/twittner/hkdf)", - "libc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sodiumoxide 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rustc-serialize" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "sodiumoxide" -version = "0.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libsodium-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", -] - diff --git a/cryptobox-c/Cargo.toml b/cryptobox-c/Cargo.toml deleted file mode 100644 index 19a9b10..0000000 --- a/cryptobox-c/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "cryptobox-c" -version = "0.5.1" -authors = ["Roman S. Borschel ", "Toralf Wittner "] -description = "C-FFI to cryptobox" -homepage = "https://github.com/shared-secret/cryptobox/cryptobox-c" -repository = "git@github.com:shared-secret/cryptobox.git" -license = "MPL-2.0" - -[lib] -name = "cryptobox" -crate-type = ["dylib"] - -[dependencies] -libc = ">= 0.1.12" - -[dependencies.proteus] -git = "https://github.com/shared-secret/proteus" -branch = "develop" - -[dependencies.cryptobox] -path = "../cryptobox" diff --git a/cryptobox-c/Makefile b/cryptobox-c/Makefile deleted file mode 100644 index 4ad0274..0000000 --- a/cryptobox-c/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -SHELL := /usr/bin/env bash -VERSION := "0.5.0" -ARCH := amd64 -BUILD ?= 1 -OS := $(shell uname -s | tr '[:upper:]' '[:lower:]') - -ifeq ($(OS), darwin) -LIB_TYPE := dylib -LIB_PATH := DYLD_LIBRARY_PATH -else -LIB_TYPE := so -LIB_PATH := LD_LIBRARY_PATH -endif - -all: compile - -clean: - cargo clean - rm -rf test/target - rm -f deb/usr/include/*.h - rm -f deb/usr/lib/*.so - -compile: - cargo build - -compile-release: - cargo build --release - -test: compile test-compile - $(LIB_PATH)=test/target valgrind --leak-check=full --error-exitcode=1 --track-origins=yes test/target/main - -test-compile: - mkdir -p test/target - cp target/debug/libcryptobox.$(LIB_TYPE) test/target/libcryptobox.$(LIB_TYPE) - rm -f test/target/main - $(CC) -std=c99 -Wall -Wextra -Werror -g test/main.c -o test/target/main -Isrc -Ltest/target -lcryptobox - -bench: bench-compile - $(LIB_PATH)=test/target test/target/bench - -bench-compile: compile-release - mkdir -p test/target - cp target/release/libcryptobox.$(LIB_TYPE) test/target/libcryptobox.$(LIB_TYPE) - rm -f test/target/bench - $(CC) -std=c99 -Wall -Wextra -Werror -g test/bench.c -o test/target/bench -Isrc -Ltest/target -lcryptobox - -install: compile-release - cp src/cbox.h /usr/local/include - cp target/release/libcryptobox.$(LIB_TYPE) /usr/local/lib - ln -s /usr/local/lib/libcryptobox.$(LIB_TYPE) /usr/local/lib/libcryptobox.$(LIB_TYPE) - -uninstall: - rm -f /usr/local/include/cbox.h - rm -f /usr/local/lib/libcryptobox.$(LIB_TYPE) - -dist: compile-release - mkdir -p deb/usr/include - mkdir -p deb/usr/lib - cp src/cbox.h deb/usr/include - cp target/release/libcryptobox.$(LIB_TYPE) deb/usr/lib -ifeq ($(OS), linux) - makedeb --name=cryptobox \ - --version=$(VERSION) \ - --debian-dir=deb \ - --build=$(BUILD) \ - --architecture=$(ARCH) \ - --output-dir=target/release -endif diff --git a/cryptobox-c/README.md b/cryptobox-c/README.md deleted file mode 100644 index 5de474f..0000000 --- a/cryptobox-c/README.md +++ /dev/null @@ -1,116 +0,0 @@ -# Cryptobox - C API [![Build Status](https://travis-ci.org/shared-secret/cryptobox.svg?branch=develop)](https://travis-ci.org/shared-secret/cryptobox) - -`cryptobox-c` provides a high-level C API for the `cryptobox` library. - -**Disclaimer: This project is an early work-in-progress.** - -## Dependencies - -[Sodium](https://github.com/jedisct1/libsodium) - -## Building - -### Compile - - make - -### Test - -[Valgrind](http://valgrind.org/) must be installed, then - - make test - -### Package - -The current build can produce a basic Debian package. [Makedeb](https://github.com/twittner/makedeb) must be installed, then - - make dist - -will place the package into `target/release/`. These debian packages are usually attached to every release and can be downloaded via github. - -## Language Bindings - - * Java / Android: A Java API through JNI with support for cross-compilation to Android is provided by [cryptobox-jni](https://github.com/shared-secret/cryptobox-jni). - * Objective-C / iOS: Cross-compiled binaries for iOS as well as an Objective-C API is provided by [cryptobox-ios](https://github.com/shared-secret/cryptobox-ios). - * Haskell: Haskell FFI bindings are available through [cryptobox-haskell](https://github.com/shared-secret/cryptobox-haskell). - -## API Overview - -The following is an API overview. For detailed function signatures, refer to the [cbox.h](cbox.h) header file. - -### CBox - -A `CBox` is an opaque container for all the necessary key material of a single client (e.g. a single device of a user). -A `CBox` is allocated with a call to `cbox_file_open`. It takes a `path` as an argument which must be a valid file path -pointing to an existing directory. That directory becomes the root directory for all data stored by that `CBox` or any of the `CBoxSession`s -obtained from it. - -> Note: Do not create multiple `CBox`es that operate on the same or overlapping directories. - -Opened `CBox`es should typically be used for an extended period of time to obtain sessions and in turn -encrypt and decrypt messages. - -> Note: Every call to `cbox_file_open` must be paired with a `cbox_close` to properly deallocate the `CBox`. - -### CBoxSession - -A `CBoxSession` represents a cryptographic session between two endpoints (e.g. devices). -Sessions are identified through a session ID, which is an opaque C string for -the `CryptoBox` API. A session ID should uniquely identify a remote client or device. - -#### Obtaining an existing session - -Before deciding to initialise a new session, a client typically tries to obtain an existing session -using `cbox_session_get`. If no session is found, the `CBOX_NO_SESSION` error code is returned. - -#### Initialising a new session - -If no session for a given session ID exists, a new session can be initialised either through -`cbox_session_init_from_prekey` or `cbox_session_init_from_message`. - -A client who wants to send a message to another client with whom no session exists obtains a prekey from its peer -(directly or indirectly) and uses `cbox_session_init_from_prekey`. - -A client who receives an encrypted message from another client with whom he has no existing session -uses `cbox_session_init_from_message`. - -#### Encrypting and decrypting messages - -Once a session is obtained it can be used to encrypt and decrypt messages via `cbox_encrypt` -and `cbox_decrypt`, respectively. - -The encrypt and decrypt operations fill `CBoxVec` structures which provide access to the encrypted or decrypted -data via `cbox_vec_data` as well as its length through `cbox_vec_len`. Once the data has been consumed and is -no longer needed, a `CBoxVec` must be freed using `cbox_vec_free`. - -> Note: Every call to `cbox_session_get`, `cbox_session_init_from_prekey` or `cbox_session_init_from_message` -must be paired with a `cbox_session_close` to properly deallocate the `CBoxSession`. - -#### Saving a session - -After successfully encrypting and/or decrypting one or more messages, a session can be saved -through `cbox_session_save`. Once a session is saved, the changes to the key material are -permanent, e.g. a decrypt operation cannot be repeated. It can therefore be advisable to -save a session only once the decrypted plaintext has been safely stored. - -### Prekeys - -In order to establish sessions, one client must be able to obtain a prekey from another. -To generate a prekey, `cbox_new_prekey` is used, which fills a `CBoxVec` with the public -key meterial of the newly generated prekey which can then be sent directly to another -client or uploaded to a server for others to download. - -### Fingerprints - -Public key fingerprints can be compared out-of-band to protect against MITM attacks. -The functions `cbox_fingerprint_local` and `cbox_fingerprint_remote` are provided for -that purpose. - -## Thread-safety - -The API is not thread-safe. However, distinct `CBox`es and `CBoxSession`s can be used -independently (and concurrently). It is up to client code or higher-level language bindings -to provide thread-safety as necessary for the desired usage pattern. - -> Note: When sessions are used concurrently, it is important to make sure not to have -> two or more sessions with the same session ID in use at the same time. diff --git a/cryptobox-c/deb/DEBIAN/control b/cryptobox-c/deb/DEBIAN/control deleted file mode 100644 index 724e802..0000000 --- a/cryptobox-c/deb/DEBIAN/control +++ /dev/null @@ -1,6 +0,0 @@ -Package: cryptobox -Version: <>+<> -Maintainer: Roman S. Borschel -Architecture: amd64 -Depends: libsodium-dev -Description: High-level C API with persistent storage for proteus diff --git a/cryptobox-c/deb/DEBIAN/postinst b/cryptobox-c/deb/DEBIAN/postinst deleted file mode 100755 index 0ffc949..0000000 --- a/cryptobox-c/deb/DEBIAN/postinst +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -e - -cd /usr/lib && ln -s libcryptobox-*.so libcryptobox.so diff --git a/cryptobox-c/deb/DEBIAN/prerm b/cryptobox-c/deb/DEBIAN/prerm deleted file mode 100755 index bbfdc06..0000000 --- a/cryptobox-c/deb/DEBIAN/prerm +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -e - -rm /usr/lib/libcryptobox.so diff --git a/cryptobox-c/src/cbox.h b/cryptobox-c/src/cbox.h deleted file mode 100644 index 4902399..0000000 --- a/cryptobox-c/src/cbox.h +++ /dev/null @@ -1,294 +0,0 @@ -#ifndef __CRYPTOBOX_H__ -#define __CRYPTOBOX_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// CBoxVec ////////////////////////////////////////////////////////////////// - -// A heap-allocated vector of bytes. -typedef struct CBoxVec CBoxVec; - -// Get a pointer to the contents of a byte vector. -uint8_t * cbox_vec_data(CBoxVec const * v); - -// Get the length of a byte vector. -size_t cbox_vec_len(CBoxVec const * v); - -// Deallocate a byte vector. -void cbox_vec_free(CBoxVec * v); - -// CBoxResult /////////////////////////////////////////////////////////////// - -// The result of an operation that might fail. -typedef enum { - CBOX_SUCCESS = 0, - - // An internal storage error occurred. - CBOX_STORAGE_ERROR = 1, - - // A CBoxSession was not found. - CBOX_SESSION_NOT_FOUND = 2, - - // An error occurred during binary decoding of a data structure. - CBOX_DECODE_ERROR = 3, - - // The (prekey-)message being decrypted contains a different - // remote identity than previously received. - CBOX_REMOTE_IDENTITY_CHANGED = 4, - - // The (prekey-)message being decrypted has an invalid signature. - // This might indicate that the message has been tampered with. - CBOX_INVALID_SIGNATURE = 5, - - // The (prekey-)message being decrypted is invalid given the - // current state of the CBoxSession. - CBOX_INVALID_MESSAGE = 6, - - // The (prekey-)message being decrypted is a duplicate and can - // be safely discarded. - CBOX_DUPLICATE_MESSAGE = 7, - - // The (prekey-)message being decrypted is out of bounds for the - // supported range of skipped / delayed messages. - CBOX_TOO_DISTANT_FUTURE = 8, - - // The (prekey-)message being decrypted is out of bounds for the - // supported range of skipped / delayed messages. - CBOX_OUTDATED_MESSAGE = 9, - - // A string argument is not utf8-encoded. - // This is typically a programmer error. - CBOX_UTF8_ERROR = 10, - - // A string argument is missing a NUL terminator. - // This is typically a programmer error. - CBOX_NUL_ERROR = 11, - - // An error occurred during binary encoding of a data structure. - CBOX_ENCODE_ERROR = 12, - - // A CBox has been opened with an incomplete or mismatching identity. - // This is typically a programmer error. - CBOX_IDENTITY_ERROR = 13, - - // An attempt was made to initialise a new session with a prekey ID - // for which no prekey could be found. - CBOX_PREKEY_NOT_FOUND = 14 -} CBoxResult; - -// CBoxIdentityMode ///////////////////////////////////////////////////////// - -// The local storage mode for an external identity in `cbox_file_open_with`. -typedef enum { - // The full identity is stored locally inside the CBox. - CBOX_IDENTITY_COMPLETE = 0, - - // Only the public identity is stored locally inside the CBox. - CBOX_IDENTITY_PUBLIC = 1 -} CBoxIdentityMode; - -// CBox ///////////////////////////////////////////////////////////////////// - -// A container of sessions and prekeys of a single peer with a long-lived -// identity which is either internally or externally managed. -typedef struct CBox CBox; - -// Open a CBox in an existing directory with an internally managed identity. -// -// The given directory is the root directory for the CBox in which -// sessions, prekeys, the long-term identity as well auxiliary data may -// be stored. If the directory is empty, it is initialised with a new -// long-term identity. -// --- -// `path` is the path to an existing directory. -// `b` is the pointer to point at the opened CBox. -CBoxResult cbox_file_open(char const * path, CBox ** b); - -// Open a CBox using an existing external identity. -// -// The given directory is the root directory for the CBox in which -// sessions, prekeys, the long-term identity as well auxiliary data may -// be stored. If the directory is empty, it is initialised with the given -// long-term identity. -// --- -// `path` is a path to an existing directory. -// `ident` is the external identity to use. An existing CBox with only -// a public local identity must always be opened with an external -// identity. -// `ident_len` is the length of `ident`. -// `mode` specifies the desired storage of the given identity inside the box. -CBoxResult cbox_file_open_with(char const * path, - uint8_t const * ident, - size_t ident_len, - CBoxIdentityMode mode, - CBox ** b); - -// Copies the serialised long-term identity from the given cryptobox. -// -// The allocated CBoxVec contains the complete long-term identity of the given -// CBox and thus sensitive private key material. It should be stored in a safe -// location and / or transmitted over a secure channel before being disposed -// in a timely manner. -// --- -// `b` is the CBox from which to copy the identity. -// `ident` is the pointer to point at the serialised identity. -CBoxResult cbox_identity_copy(CBox const * b, CBoxVec ** ident); - -// Close a CBox, freeing the memory associated with it. -// -// A CBox should only be closed after all sessions acquired through it have -// been closed. Any remaining open sessions that were obtained from the box -// can no longer be used with the exception of being closed via `cbox_session_close`. -void cbox_close(CBox * b); - -// Prekeys ////////////////////////////////////////////////////////////////// - -// The ID of the "last resort" prekey, which is never removed. -extern const uint16_t CBOX_LAST_PREKEY_ID; - -// Generate a new prekey, returning the public prekey material for usage by a -// peer to initialise a session. -// -// If a prekey with the same ID already exists, it is replaced. -// --- -// `b` is the CBox in which to create the new prekey. -// `prekey` is the pointer to point at the public key material of the new -// prekey for usage by a peer. -CBoxResult cbox_new_prekey(CBox const * b, uint16_t id, CBoxVec ** prekey); - -// CBoxSession ////////////////////////////////////////////////////////////// - -// A cryptographic session with a peer. -typedef struct CBoxSession CBoxSession; - -// Initialise a session from a public prekey of a peer. -// -// This is the entry point for the sender of a message, if no session exists. -// --- -// `b` is the box in which the session is created. The session will be bound -// to the lifetime of the box and can only be used until either the -// session or the box is closed. -// `sid` is a unique ID to use for the new session. -// `peer_prekey` is the public prekey of the peer. -// `peer_prekey_len` is the length (in bytes) of the `peer_prekey`. -// `s` is the pointer to point at the successfully initialised session. -CBoxResult cbox_session_init_from_prekey(CBox const * b, - char const * sid, - uint8_t const * peer_prekey, - size_t peer_prekey_len, - CBoxSession ** s); - -// Initialise a session from a ciphertext message. -// -// This is the entry point for the recipient of a message, if no session exists. -// --- -// `b` is the box in which the session is created. The session will be bound -// to the lifetime of the box and can only be used until either the -// session or the box is closed. -// `sid` is a unique ID to use for the new session. -// `cipher` is the received ciphertext message. -// `cipher_len` is the length (in bytes) of `cipher`. -// `s` is the pointer to point at the successfully initialised session. -// `plain` is the pointer to point at the successfully decrypted message. -CBoxResult cbox_session_init_from_message(CBox const * b, - char const * sid, - uint8_t const * cipher, - size_t cipher_len, - CBoxSession ** s, - CBoxVec ** plain); - -// Lookup a session by ID. -// -// If the session is not found, `CBOX_SESSION_NOT_FOUND` is returned and `s` will -// be unchanged. -// --- -// `b` is the box in which to look for the session. The session will be bound -// to the lifetime of the box and can only be used until either the -// session or the box is closed. -// `sid` is the session ID to look for. -// `s` is the pointer to point at the session, if it is found. -CBoxResult cbox_session_load(CBox const * b, char const * sid, CBoxSession ** s); - -// Save a session. -// -// Saving a session makes any changes to the key material as a result of -// `cbox_encrypt` and `cbox_decrypt` permanent. Newly initialised sessions -// as a result of `cbox_session_init_from_message` and `cbox_session_init_from_prekey` -// are also only persisted (and prekeys ultimately removed) when saved, to -// facilitate retries in case of intermittent failure. -// -// A session should always be saved before sending newly obtained ciphertext to -// a peer, as well as after decrypting one or more received messages. -// --- -// `s` is the session to save. -CBoxResult cbox_session_save(CBox const * b, CBoxSession * s); - -// Close a session, freeing the memory associated with it. -// -// After a session has been closed, it must no longer be used. -void cbox_session_close(CBoxSession * s); - -// Delete an existing session. -// -// If the session does not exist, this function does nothing. -CBoxResult cbox_session_delete(CBox const * b, char const * sid); - -// Encrypt a plaintext message. -// --- -// `s` is the session to use for encryption. -// `plain` is the plaintext to encrypt. -// `plain_len` is the length of `plain`. -// `cipher` is the pointer to point at the resulting ciphertext. -CBoxResult cbox_encrypt(CBoxSession * s, - uint8_t const * plain, - size_t plain_len, - CBoxVec ** cipher); - -// Decrypt a ciphertext nessage. -// --- -// `s` is the session to use for decryption. -// `cipher` is the ciphertext to decrypt. -// `cipher_len` is the length of `cipher`. -// `plain` is the pointer to point at the resulting plaintext. -CBoxResult cbox_decrypt(CBoxSession * s, - uint8_t const * cipher, - size_t cipher_len, - CBoxVec ** plain); - -// Get the public key fingerprint of the local identity. -// -// The fingerprint is represented as a hex-encoded byte sequence. -// --- -// `b` is the box from which to obtain the fingerprint. -// `fp` is the pointer to point at the fingerprint. -void cbox_fingerprint_local(CBox const * b, CBoxVec ** fp); - -// Get the public key fingerprint of the remote identity associated with -// the given session. -// -// The fingerprint is represented as a hex-encoded byte sequence. -// --- -// `s` is the session from which to obtain the fingerprint of the remote peer. -// `fp` is the pointer to point at the fingerprint. -void cbox_fingerprint_remote(CBoxSession const * s, CBoxVec ** fp); - -// Utilities //////////////////////////////////////////////////////////////// - -// Generate `len` cryptographically strong random bytes. -// -// Returns a pointer to the allocated random bytes. -// --- -// `b` is the CBox that serves as the initialised context for obtaining -// randomness. -// `len` is the number of random bytes to generate. -CBoxVec * cbox_random_bytes(CBox const * b, size_t len); - -#ifdef __cplusplus -} -#endif - -#endif // __CRYPTOBOX_H__ diff --git a/cryptobox-c/src/lib.rs b/cryptobox-c/src/lib.rs deleted file mode 100644 index a607770..0000000 --- a/cryptobox-c/src/lib.rs +++ /dev/null @@ -1,307 +0,0 @@ -// This Source Code Form is subject to the terms of -// the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You -// can obtain one at http://mozilla.org/MPL/2.0/. - -extern crate cryptobox; -extern crate libc; -extern crate proteus; - -use cryptobox::{CBox, CBoxError, CBoxSession, Identity, IdentityMode}; -use cryptobox::store::Store; -use cryptobox::store::file::FileStore; -use libc::{c_char, c_ushort, size_t, uint8_t}; -use proteus::{DecodeError, EncodeError}; -use proteus::keys::{self, PreKeyId}; -use proteus::session::DecryptError; -use std::borrow::Cow; -use std::ffi::{CStr, NulError}; -use std::fmt; -use std::path::Path; -use std::{slice, str, u16}; - -mod log; - -/// Variant of std::try! that returns the unwrapped error. -macro_rules! try_unwrap { - ($expr:expr) => (match $expr { - Ok(val) => val, - Err(err) => return From::from(err) - }) -} - -#[repr(C)] -#[no_mangle] -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum CBoxIdentityMode { - Complete = 0, - Public = 1 -} - -#[no_mangle] -pub extern -fn cbox_file_open(c_path: *const c_char, out: *mut *mut CBox) -> CBoxResult { - let path = try_unwrap!(to_str(c_path)); - let cbox = try_unwrap!(CBox::file_open(&Path::new(path))); - assign(out, Box::new(cbox)); - CBoxResult::Success -} - -#[no_mangle] -pub extern -fn cbox_file_open_with(c_path: *const c_char, - c_id: *const uint8_t, - c_id_len: size_t, - c_mode: CBoxIdentityMode, - out: *mut *mut CBox) -> CBoxResult -{ - let path = try_unwrap!(to_str(c_path)); - let id_slice = try_unwrap!(to_slice(c_id, c_id_len as usize)); - let ident = match try_unwrap!(Identity::deserialise(id_slice)) { - Identity::Sec(i) => i.into_owned(), - Identity::Pub(_) => return CBoxResult::IdentityError - }; - let mode = match c_mode { - CBoxIdentityMode::Complete => IdentityMode::Complete, - CBoxIdentityMode::Public => IdentityMode::Public - }; - let cbox = try_unwrap!(CBox::file_open_with(&Path::new(path), ident, mode)); - assign(out, Box::new(cbox)); - CBoxResult::Success -} - -#[no_mangle] -pub extern fn cbox_close(b: *mut CBox) { - unsafe { Box::from_raw(b); } -} - -#[no_mangle] -pub extern -fn cbox_identity_copy(cbox: &CBox, out: *mut *mut Vec) -> CBoxResult { - let i = try_unwrap!(Identity::Sec(Cow::Borrowed(cbox.identity())).serialise()); - assign(out, Box::new(i)); - CBoxResult::Success -} - -#[no_mangle] -pub extern -fn cbox_session_save(cbox: &CBox, s: &mut CBoxSession) -> CBoxResult { - try_unwrap!(cbox.session_save(s)); - CBoxResult::Success -} - -#[no_mangle] -pub extern -fn cbox_session_delete(cbox: &CBox, c_sid: *const c_char) -> CBoxResult { - let sid = try_unwrap!(to_str(c_sid)); - try_unwrap!(cbox.session_delete(sid)); - CBoxResult::Success -} - -#[no_mangle] -pub fn cbox_random_bytes(_: &CBox, n: size_t) -> *mut Vec { - Box::into_raw(Box::new(keys::rand_bytes(n as usize))) -} - -// Prekeys ////////////////////////////////////////////////////////////////// - -#[no_mangle] -pub static CBOX_LAST_PREKEY_ID: c_ushort = u16::MAX; - -#[no_mangle] -pub extern -fn cbox_new_prekey(cbox: &CBox, pkid: c_ushort, out: *mut *mut Vec) -> CBoxResult { - let bundle = try_unwrap!(cbox.new_prekey(PreKeyId::new(pkid))); - let bytes = try_unwrap!(bundle.serialise()); - assign(out, Box::new(bytes)); - CBoxResult::Success -} - -// Session ////////////////////////////////////////////////////////////////// - -#[no_mangle] -pub extern fn cbox_session_init_from_prekey<'r> - (cbox: &'r CBox, - c_sid: *const c_char, - c_prekey: *const uint8_t, - c_prekey_len: size_t, - out: *mut *mut CBoxSession<'r, FileStore>) -> CBoxResult -{ - let sid = try_unwrap!(to_str(c_sid)); - let prekey = try_unwrap!(to_slice(c_prekey, c_prekey_len as usize)); - let session = try_unwrap!(cbox.session_from_prekey(String::from(sid), prekey)); - assign(out, Box::new(session)); - CBoxResult::Success -} - -#[no_mangle] -pub extern fn cbox_session_init_from_message<'r> - (cbox: &'r CBox, - c_sid: *const c_char, - c_cipher: *const uint8_t, - c_cipher_len: size_t, - c_sess: *mut *mut CBoxSession<'r, FileStore>, - c_plain: *mut *mut Vec) -> CBoxResult -{ - let sid = try_unwrap!(to_str(c_sid)); - let env = try_unwrap!(to_slice(c_cipher, c_cipher_len as usize)); - let (s, v) = try_unwrap!(cbox.session_from_message(String::from(sid), env)); - assign(c_plain, Box::new(v)); - assign(c_sess, Box::new(s)); - CBoxResult::Success -} - -#[no_mangle] -pub extern fn cbox_session_load<'r> - (cbox: &'r CBox, - c_sid: *const c_char, - out: *mut *mut CBoxSession<'r, FileStore>) -> CBoxResult -{ - let sid = try_unwrap!(to_str(c_sid)); - let session = match try_unwrap!(cbox.session_load(String::from(sid))) { - None => return CBoxResult::SessionNotFound, - Some(s) => s - }; - assign(out, Box::new(session)); - CBoxResult::Success -} - -#[no_mangle] -pub extern fn cbox_session_close(b: *mut CBoxSession) { - unsafe { Box::from_raw(b); } -} - -#[no_mangle] -pub extern fn cbox_encrypt - (session: &mut CBoxSession, - c_plain: *const uint8_t, - c_plain_len: size_t, - out: *mut *mut Vec) -> CBoxResult -{ - let plain = try_unwrap!(to_slice(c_plain, c_plain_len as usize)); - let cipher = try_unwrap!(session.encrypt(plain)); - assign(out, Box::new(cipher)); - CBoxResult::Success -} - -#[no_mangle] -pub extern fn cbox_decrypt - (session: &mut CBoxSession, - c_cipher: *const uint8_t, - c_cipher_len: size_t, - out: *mut *mut Vec) -> CBoxResult -{ - let env = try_unwrap!(to_slice(c_cipher, c_cipher_len as usize)); - let plain = try_unwrap!(session.decrypt(env)); - assign(out, Box::new(plain)); - CBoxResult::Success -} - -#[no_mangle] -pub extern -fn cbox_fingerprint_local(b: &CBox, out: *mut *mut Vec) { - let fp = b.fingerprint().into_bytes(); - assign(out, Box::new(fp)) -} - -#[no_mangle] -pub extern -fn cbox_fingerprint_remote(session: &CBoxSession, out: *mut *mut Vec) { - let fp = session.fingerprint_remote().into_bytes(); - assign(out, Box::new(fp)) -} - -// CBoxVec ////////////////////////////////////////////////////////////////// - -#[no_mangle] -pub extern fn cbox_vec_free(b: *mut Vec) { - unsafe { Box::from_raw(b); } -} - -#[no_mangle] -pub extern fn cbox_vec_data(v: &Vec) -> *const uint8_t { - v.as_ptr() -} - -#[no_mangle] -pub extern fn cbox_vec_len(v: &Vec) -> size_t { - v.len() as size_t -} - -// Unsafe /////////////////////////////////////////////////////////////////// - -fn to_str<'r>(s: *const c_char) -> Result<&'r str, str::Utf8Error> { - unsafe { CStr::from_ptr(s).to_str() } -} - -fn to_slice<'r, A>(xs: *const A, len: usize) -> Result<&'r [A], CBoxResult> { - unsafe { Ok(slice::from_raw_parts(xs, len)) } -} - -fn assign(to: *mut *mut A, from: Box) { - unsafe { *to = Box::into_raw(from) } -} - -// CBoxResult /////////////////////////////////////////////////////////////// - -#[repr(C)] -#[no_mangle] -#[derive(Clone, Copy, Debug)] -pub enum CBoxResult { - Success = 0, - StorageError = 1, - SessionNotFound = 2, - DecodeError = 3, - RemoteIdentityChanged = 4, - InvalidSignature = 5, - InvalidMessage = 6, - DuplicateMessage = 7, - TooDistantFuture = 8, - OutdatedMessage = 9, - Utf8Error = 10, - NulError = 11, - EncodeError = 12, - IdentityError = 13, - PreKeyNotFound = 14 -} - -impl From> for CBoxResult { - fn from(e: CBoxError) -> CBoxResult { - let _ = log::error(&e); - match e { - CBoxError::DecryptError(DecryptError::RemoteIdentityChanged) => CBoxResult::RemoteIdentityChanged, - CBoxError::DecryptError(DecryptError::InvalidSignature) => CBoxResult::InvalidSignature, - CBoxError::DecryptError(DecryptError::InvalidMessage) => CBoxResult::InvalidMessage, - CBoxError::DecryptError(DecryptError::DuplicateMessage) => CBoxResult::DuplicateMessage, - CBoxError::DecryptError(DecryptError::TooDistantFuture) => CBoxResult::TooDistantFuture, - CBoxError::DecryptError(DecryptError::OutdatedMessage) => CBoxResult::OutdatedMessage, - CBoxError::DecryptError(DecryptError::PreKeyNotFound(_)) => CBoxResult::PreKeyNotFound, - CBoxError::DecryptError(DecryptError::PreKeyStoreError(_)) => CBoxResult::StorageError, - CBoxError::StorageError(_) => CBoxResult::StorageError, - CBoxError::DecodeError(_) => CBoxResult::DecodeError, - CBoxError::EncodeError(_) => CBoxResult::EncodeError, - CBoxError::IdentityError => CBoxResult::IdentityError - } - } -} - -impl From for CBoxResult { - fn from(e: str::Utf8Error) -> CBoxResult { - let _ = log::error(&e); - CBoxResult::Utf8Error - } -} - -impl From for CBoxResult { - fn from(e: DecodeError) -> CBoxResult { - let _ = log::error(&e); - CBoxResult::DecodeError - } -} - -impl From for CBoxResult { - fn from(e: EncodeError) -> CBoxResult { - let _ = log::error(&e); - CBoxResult::EncodeError - } -} diff --git a/cryptobox-c/src/log.rs b/cryptobox-c/src/log.rs deleted file mode 100644 index 8553757..0000000 --- a/cryptobox-c/src/log.rs +++ /dev/null @@ -1,54 +0,0 @@ -// This Source Code Form is subject to the terms of -// the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You -// can obtain one at http://mozilla.org/MPL/2.0/. - -use std::error::Error; -use std::io::Result; - -pub fn error(e: &E) -> Result<()> { - target::error(e) -} - -// ANDROID ////////////////////////////////////////////////////////////////// - -#[cfg(target_os = "android")] -mod target { - use libc::{c_char, c_int}; - use std::error::Error; - use std::ffi::CStr; - use std::io::Result; - - const TAG: &'static str = "CryptoBox\0"; - const LEVEL_ERROR: c_int = 6; - - pub fn error(e: &E) -> Result<()> { - log(&format!("{}\0", e), LEVEL_ERROR) - } - - fn log(msg: &str, lvl: c_int) -> Result<()> { - unsafe { - let tag = CStr::from_ptr(TAG.as_ptr() as *const c_char); - let msg = CStr::from_ptr(msg.as_ptr() as *const c_char); - __android_log_write(lvl, tag.as_ptr(), msg.as_ptr()); - } - Ok(()) - } - - #[link(name = "log")] - extern { - fn __android_log_write(prio: c_int, tag: *const c_char, text: *const c_char) -> c_int; - } -} - -// FALLBACK ///////////////////////////////////////////////////////////////// - -#[cfg(not(target_os = "android"))] -mod target { - use std::error::Error; - use std::io::{Write, stderr, Result}; - - pub fn error(e: &E) -> Result<()> { - writeln!(&mut stderr(), "ERROR: {}", e) - } -} diff --git a/cryptobox-c/test/bench.c b/cryptobox-c/test/bench.c deleted file mode 100644 index 35deae7..0000000 --- a/cryptobox-c/test/bench.c +++ /dev/null @@ -1,86 +0,0 @@ -#ifdef __APPLE__ -#include -#else -#define _POSIX_C_SOURCE 200809L -#endif - -#include -#include -#include -#include -#include -#include - -double get_time() { - struct timeval t; - gettimeofday(&t, NULL); - return t.tv_sec + t.tv_usec*1e-6; -} - -void bench_session_save(CBox * alice_box, CBox * bob_box) { - printf("bench_session_save ... "); - - CBoxResult rc = CBOX_SUCCESS; - - // Bob prekey - CBoxVec * bob_prekey = NULL; - rc = cbox_new_prekey(bob_box, 1, &bob_prekey); - assert(rc == CBOX_SUCCESS); - - // Alice - CBoxSession * alice = NULL; - rc = cbox_session_init_from_prekey(alice_box, "alice", cbox_vec_data(bob_prekey), cbox_vec_len(bob_prekey), &alice); - assert(rc == CBOX_SUCCESS); - rc = cbox_session_save(alice_box, alice); - assert(rc == CBOX_SUCCESS); - uint8_t const hello_bob[] = "Hello Bob!"; - CBoxVec * cipher = NULL; - rc = cbox_encrypt(alice, hello_bob, sizeof(hello_bob), &cipher); - assert(rc == CBOX_SUCCESS); - - // Bob - CBoxSession * bob = NULL; - CBoxVec * plain = NULL; - rc = cbox_session_init_from_message(bob_box, "bob", cbox_vec_data(cipher), cbox_vec_len(cipher), &bob, &plain); - assert(rc == CBOX_SUCCESS); - - double start = get_time(); - for (int i = 0; i < 1000; ++i) { - cbox_session_save(bob_box, bob); - } - double end = get_time(); - - printf("OK (%fs)\n", end - start); -} - -int main() { - // Setup Alice's & Bob's crypto boxes - char alice_tmp[] = "/tmp/cbox_test_aliceXXXXXX"; - char * alice_dir = mkdtemp(alice_tmp); - assert(alice_dir != NULL); - - char bob_tmp[] = "/tmp/cbox_test_bobXXXXXX"; - char * bob_dir = mkdtemp(bob_tmp); - assert(bob_dir != NULL); - - printf("alice=\"%s\", bob=\"%s\"\n", alice_tmp, bob_tmp); - - CBoxResult rc = CBOX_SUCCESS; - - CBox * alice_box = NULL; - rc = cbox_file_open(alice_dir, &alice_box); - assert(rc == CBOX_SUCCESS); - assert(alice_box != NULL); - - CBox * bob_box = NULL; - rc = cbox_file_open(bob_dir, &bob_box); - assert(rc == CBOX_SUCCESS); - assert(bob_box != NULL); - - // Run benchmarks - bench_session_save(alice_box, bob_box); - - // Cleanup - cbox_close(alice_box); - cbox_close(bob_box); -} diff --git a/cryptobox-c/test/main.c b/cryptobox-c/test/main.c deleted file mode 100644 index a170ada..0000000 --- a/cryptobox-c/test/main.c +++ /dev/null @@ -1,406 +0,0 @@ -#ifdef __APPLE__ -#include -#else -#define _POSIX_C_SOURCE 200809L -#endif - -#include -#include -#include -#include -#include - -void print_hex(unsigned char const * dat, unsigned short len) { - for (int i = 0; i < len; ++i) { - printf("%02x ", dat[i]); - } - printf("\n"); -} - -void test_basics(CBox * alice_box, CBox * bob_box) { - printf("test_basics ... "); - - CBoxResult rc = CBOX_SUCCESS; - - // Bob prekey - CBoxVec * bob_prekey = NULL; - rc = cbox_new_prekey(bob_box, 1, &bob_prekey); - assert(rc == CBOX_SUCCESS); - - // Alice - CBoxSession * alice = NULL; - rc = cbox_session_init_from_prekey(alice_box, "alice", cbox_vec_data(bob_prekey), cbox_vec_len(bob_prekey), &alice); - assert(rc == CBOX_SUCCESS); - rc = cbox_session_save(alice_box, alice); - assert(rc == CBOX_SUCCESS); - uint8_t const hello_bob[] = "Hello Bob!"; - CBoxVec * cipher = NULL; - rc = cbox_encrypt(alice, hello_bob, sizeof(hello_bob), &cipher); - assert(rc == CBOX_SUCCESS); - assert(strncmp((char const *) hello_bob, (char const *) cbox_vec_data(cipher), cbox_vec_len(cipher)) != 0); - - // Bob - CBoxSession * bob = NULL; - CBoxVec * plain = NULL; - rc = cbox_session_init_from_message(bob_box, "bob", cbox_vec_data(cipher), cbox_vec_len(cipher), &bob, &plain); - assert(rc == CBOX_SUCCESS); - cbox_session_save(bob_box, bob); - - assert(strncmp((char const *) hello_bob, (char const *) cbox_vec_data(plain), cbox_vec_len(plain)) == 0); - - // Compare fingerprints - CBoxVec * local = NULL; - CBoxVec * remote = NULL; - - cbox_fingerprint_local(alice_box, &local); - cbox_fingerprint_remote(bob, &remote); - assert(strncmp((char const *) cbox_vec_data(local), (char const *) cbox_vec_data(remote), cbox_vec_len(remote)) == 0); - cbox_vec_free(remote); - cbox_vec_free(local); - - cbox_fingerprint_local(bob_box, &local); - cbox_fingerprint_remote(alice, &remote); - assert(strncmp((char const *) cbox_vec_data(local), (char const *) cbox_vec_data(remote), cbox_vec_len(remote)) == 0); - cbox_vec_free(remote); - cbox_vec_free(local); - - // Load the sessions again - cbox_session_close(alice); - cbox_session_close(bob); - rc = cbox_session_load(alice_box, "alice", &alice); - assert(rc == CBOX_SUCCESS); - rc = cbox_session_load(bob_box, "bob", &bob); - assert(rc == CBOX_SUCCESS); - - // unknown session - CBoxSession * unknown = NULL; - rc = cbox_session_load(alice_box, "unknown", &unknown); - assert(rc == CBOX_SESSION_NOT_FOUND); - - // Cleanup - cbox_vec_free(cipher); - cbox_vec_free(plain); - cbox_vec_free(bob_prekey); - - cbox_session_close(alice); - cbox_session_close(bob); - - printf("OK\n"); -} - -void test_prekey_removal(CBox * alice_box, CBox * bob_box) { - printf("test_prekey_removal ... "); - CBoxResult rc = CBOX_SUCCESS; - - // Bob prekey - CBoxVec * bob_prekey = NULL; - rc = cbox_new_prekey(bob_box, 1, &bob_prekey); - assert(rc == CBOX_SUCCESS); - - // Alice - CBoxSession * alice = NULL; - rc = cbox_session_init_from_prekey(alice_box, "alice", cbox_vec_data(bob_prekey), cbox_vec_len(bob_prekey), &alice); - assert(rc == CBOX_SUCCESS); - uint8_t const hello_bob[] = "Hello Bob!"; - CBoxVec * cipher = NULL; - rc = cbox_encrypt(alice, hello_bob, sizeof(hello_bob), &cipher); - assert(rc == CBOX_SUCCESS); - - // Bob - CBoxSession * bob = NULL; - CBoxVec * plain = NULL; - rc = cbox_session_init_from_message(bob_box, "bob", cbox_vec_data(cipher), cbox_vec_len(cipher), &bob, &plain); - assert(rc == CBOX_SUCCESS); - - // Pretend something happened before Bob could save his session and he retries. - // The prekey should not be removed (yet). - cbox_session_close(bob); - cbox_vec_free(plain); - rc = cbox_session_init_from_message(bob_box, "bob", cbox_vec_data(cipher), cbox_vec_len(cipher), &bob, &plain); - assert(rc == CBOX_SUCCESS); - - cbox_session_save(bob_box, bob); - - // Now the prekey should be gone - cbox_session_close(bob); - cbox_vec_free(plain); - rc = cbox_session_init_from_message(bob_box, "bob", cbox_vec_data(cipher), cbox_vec_len(cipher), &bob, &plain); - assert(rc == CBOX_PREKEY_NOT_FOUND); - - // Cleanup - cbox_vec_free(bob_prekey); - cbox_vec_free(cipher); - cbox_session_close(alice); - - printf("OK\n"); -} - -void test_random_bytes(CBox const * b) { - printf("test_random_bytes ... "); - CBoxVec * random = cbox_random_bytes(b, 16); - assert(16 == cbox_vec_len(random)); - cbox_vec_free(random); - printf("OK\n"); -} - -void test_last_prekey(CBox * alice_box, CBox * bob_box) { - printf("test_last_prekey ... "); - CBoxVec * bob_prekey = NULL; - CBoxResult rc = cbox_new_prekey(bob_box, CBOX_LAST_PREKEY_ID, &bob_prekey); - assert(rc == CBOX_SUCCESS); - - // Alice - CBoxSession * alice = NULL; - rc = cbox_session_init_from_prekey(alice_box, "alice", cbox_vec_data(bob_prekey), cbox_vec_len(bob_prekey), &alice); - cbox_vec_free(bob_prekey); - assert(rc == CBOX_SUCCESS); - uint8_t const hello_bob[] = "Hello Bob!"; - CBoxVec * cipher = NULL; - rc = cbox_encrypt(alice, hello_bob, sizeof(hello_bob), &cipher); - assert(rc == CBOX_SUCCESS); - - // Bob - CBoxSession * bob = NULL; - CBoxVec * plain = NULL; - rc = cbox_session_init_from_message(bob_box, "bob", cbox_vec_data(cipher), cbox_vec_len(cipher), &bob, &plain); - assert(rc == CBOX_SUCCESS); - - cbox_session_save(bob_box, bob); - cbox_session_close(bob); - cbox_vec_free(plain); - - // Bob's last prekey is not removed - rc = cbox_session_init_from_message(bob_box, "bob", cbox_vec_data(cipher), cbox_vec_len(cipher), &bob, &plain); - assert(rc == CBOX_SUCCESS); - - cbox_vec_free(plain); - cbox_vec_free(cipher); - cbox_session_close(alice); - cbox_session_close(bob); - printf("OK\n"); -} - -void test_duplicate_msg(CBox * alice_box, CBox * bob_box) { - printf("test_duplicate_msg ... "); - CBoxVec * bob_prekey = NULL; - CBoxResult rc = cbox_new_prekey(bob_box, 0, &bob_prekey); - assert(rc == CBOX_SUCCESS); - - // Alice - CBoxSession * alice = NULL; - rc = cbox_session_init_from_prekey(alice_box, "alice", cbox_vec_data(bob_prekey), cbox_vec_len(bob_prekey), &alice); - cbox_vec_free(bob_prekey); - assert(rc == CBOX_SUCCESS); - uint8_t const hello_bob[] = "Hello Bob!"; - CBoxVec * cipher = NULL; - rc = cbox_encrypt(alice, hello_bob, sizeof(hello_bob), &cipher); - assert(rc == CBOX_SUCCESS); - - // Bob - CBoxSession * bob = NULL; - CBoxVec * plain = NULL; - rc = cbox_session_init_from_message(bob_box, "bob", cbox_vec_data(cipher), cbox_vec_len(cipher), &bob, &plain); - assert(rc == CBOX_SUCCESS); - cbox_vec_free(plain); - - rc = cbox_decrypt(bob, cbox_vec_data(cipher), cbox_vec_len(cipher), &plain); - assert(rc == CBOX_DUPLICATE_MESSAGE); - - cbox_vec_free(cipher); - cbox_session_close(alice); - cbox_session_close(bob); - printf("OK\n"); -} - -void test_delete_session(CBox * alice_box, CBox * bob_box) { - printf("test_delete_session ... "); - CBoxVec * bob_prekey = NULL; - CBoxResult rc = cbox_new_prekey(bob_box, 0, &bob_prekey); - assert(rc == CBOX_SUCCESS); - - CBoxSession * alice = NULL; - rc = cbox_session_init_from_prekey(alice_box, "alice", cbox_vec_data(bob_prekey), cbox_vec_len(bob_prekey), &alice); - cbox_vec_free(bob_prekey); - assert(rc == CBOX_SUCCESS); - - rc = cbox_session_save(alice_box, alice); - assert(rc == CBOX_SUCCESS); - cbox_session_close(alice); - - rc = cbox_session_delete(alice_box, "alice"); - assert(rc == CBOX_SUCCESS); - - rc = cbox_session_load(alice_box, "alice", &alice); - assert(rc == CBOX_SESSION_NOT_FOUND); - - // no-op, session does not exist - rc = cbox_session_delete(alice_box, "alice"); - assert(rc == CBOX_SUCCESS); - printf("OK\n"); -} - -void test_box_reopen() { - printf("test_box_reopen ... "); - CBoxResult rc = CBOX_SUCCESS; - char tmp[] = "/tmp/cbox_test_reopenXXXXXX"; - char * dir = mkdtemp(tmp); - assert(dir != NULL); - - CBox * box = NULL; - rc = cbox_file_open(dir, &box); - assert(rc == CBOX_SUCCESS); - assert(box != NULL); - - cbox_close(box); - - rc = cbox_file_open(dir, &box); - assert(rc == CBOX_SUCCESS); - assert(box != NULL); - - cbox_close(box); - printf("OK\n"); -} - -void test_external_identity() { - printf("test_external_identity ... "); - CBoxResult rc = CBOX_SUCCESS; - char tmp[] = "/tmp/cbox_test_external_identityXXXXXX"; - char * dir = mkdtemp(tmp); - assert(dir != NULL); - - CBox * box = NULL; - rc = cbox_file_open(dir, &box); - assert(rc == CBOX_SUCCESS); - assert(box != NULL); - - CBoxVec * id = NULL; - rc = cbox_identity_copy(box, &id); - assert(rc == CBOX_SUCCESS); - assert(id != NULL); - - cbox_close(box); - - // "downgrade" to public local identity - rc = cbox_file_open_with(dir, cbox_vec_data(id), cbox_vec_len(id), CBOX_IDENTITY_PUBLIC, &box); - assert(rc == CBOX_SUCCESS); - cbox_close(box); - - // not providing the full identity yields an error - rc = cbox_file_open(dir, &box); - assert(rc == CBOX_IDENTITY_ERROR); - - // open in externally managed mode - rc = cbox_file_open_with(dir, cbox_vec_data(id), cbox_vec_len(id), CBOX_IDENTITY_PUBLIC, &box); - assert(rc == CBOX_SUCCESS); - assert(box != NULL); - - cbox_close(box); - - // "upgrade" to full local identity - rc = cbox_file_open_with(dir, cbox_vec_data(id), cbox_vec_len(id), CBOX_IDENTITY_COMPLETE, &box); - assert(rc == CBOX_SUCCESS); - cbox_close(box); - - rc = cbox_file_open(dir, &box); - assert(rc == CBOX_SUCCESS); - cbox_close(box); - - cbox_vec_free(id); - - printf("OK\n"); -} - -void test_wrong_identity() { - printf("test_wrong_identity ... "); - CBoxResult rc = CBOX_SUCCESS; - - char tmp1[] = "/tmp/cbox_test_wrong_identityXXXXXX"; - char * dir1 = mkdtemp(tmp1); - assert(dir1 != NULL); - - char tmp2[] = "/tmp/cbox_test_wrong_identityXXXXXX"; - char * dir2 = mkdtemp(tmp2); - assert(dir2 != NULL); - - CBox * box1 = NULL; - rc = cbox_file_open(dir1, &box1); - assert(rc == CBOX_SUCCESS); - assert(box1 != NULL); - - CBox * box2 = NULL; - rc = cbox_file_open(dir2, &box2); - assert(rc == CBOX_SUCCESS); - assert(box2 != NULL); - - CBoxVec * id1 = NULL; - rc = cbox_identity_copy(box1, &id1); - assert(rc == CBOX_SUCCESS); - assert(id1 != NULL); - - CBoxVec * id2 = NULL; - rc = cbox_identity_copy(box2, &id2); - assert(rc == CBOX_SUCCESS); - assert(id2 != NULL); - - cbox_close(box1); - cbox_close(box2); - - // Wrong identity triggers an error - rc = cbox_file_open_with(dir1, cbox_vec_data(id2), cbox_vec_len(id2), CBOX_IDENTITY_PUBLIC, &box1); - assert(rc == CBOX_IDENTITY_ERROR); - rc = cbox_file_open_with(dir2, cbox_vec_data(id1), cbox_vec_len(id1), CBOX_IDENTITY_PUBLIC, &box2); - assert(rc == CBOX_IDENTITY_ERROR); - - rc = cbox_file_open_with(dir1, cbox_vec_data(id1), cbox_vec_len(id1), CBOX_IDENTITY_PUBLIC, &box1); - assert(rc == CBOX_SUCCESS); - rc = cbox_file_open_with(dir2, cbox_vec_data(id2), cbox_vec_len(id2), CBOX_IDENTITY_PUBLIC, &box2); - assert(rc == CBOX_SUCCESS); - - cbox_close(box1); - cbox_close(box2); - - cbox_vec_free(id1); - cbox_vec_free(id2); - - printf("OK\n"); -} - -int main() { - // Setup Alice's & Bob's crypto boxes - char alice_tmp[] = "/tmp/cbox_test_aliceXXXXXX"; - char * alice_dir = mkdtemp(alice_tmp); - assert(alice_dir != NULL); - - char bob_tmp[] = "/tmp/cbox_test_bobXXXXXX"; - char * bob_dir = mkdtemp(bob_tmp); - assert(bob_dir != NULL); - - printf("alice=\"%s\", bob=\"%s\"\n", alice_tmp, bob_tmp); - - CBoxResult rc = CBOX_SUCCESS; - - CBox * alice_box = NULL; - rc = cbox_file_open(alice_dir, &alice_box); - assert(rc == CBOX_SUCCESS); - assert(alice_box != NULL); - - CBox * bob_box = NULL; - rc = cbox_file_open(bob_dir, &bob_box); - assert(rc == CBOX_SUCCESS); - assert(bob_box != NULL); - - // Run test cases - test_basics(alice_box, bob_box); - test_prekey_removal(alice_box, bob_box); - test_random_bytes(alice_box); - test_last_prekey(alice_box, bob_box); - test_duplicate_msg(alice_box, bob_box); - test_delete_session(alice_box, bob_box); - test_box_reopen(); - test_external_identity(); - test_wrong_identity(); - - // Cleanup - cbox_close(alice_box); - cbox_close(bob_box); -} diff --git a/cryptobox/LICENSE b/cryptobox/LICENSE deleted file mode 100644 index a612ad9..0000000 --- a/cryptobox/LICENSE +++ /dev/null @@ -1,373 +0,0 @@ -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. diff --git a/cryptobox/src/identity.rs b/src/identity.rs similarity index 100% rename from cryptobox/src/identity.rs rename to src/identity.rs diff --git a/cryptobox/src/lib.rs b/src/lib.rs similarity index 100% rename from cryptobox/src/lib.rs rename to src/lib.rs diff --git a/cryptobox/src/store/file.rs b/src/store/file.rs similarity index 100% rename from cryptobox/src/store/file.rs rename to src/store/file.rs diff --git a/cryptobox/src/store/mod.rs b/src/store/mod.rs similarity index 100% rename from cryptobox/src/store/mod.rs rename to src/store/mod.rs