From dd291079f30e386b726563fdd1e2d6e43842950c Mon Sep 17 00:00:00 2001 From: SergeySeroshtan Date: Mon, 2 Sep 2019 12:11:32 +0300 Subject: [PATCH 1/9] Bump version to the v0.10.2-dev1 [ci skip] --- CMakeLists.txt | 4 ++-- VERSION | 2 +- VSCCrypto.podspec | 4 ++-- codegen/main.xml | 2 +- codegen/models/project_common/project_common.xml | 2 +- codegen/models/project_foundation/project_foundation.xml | 2 +- codegen/models/project_phe/project_phe.xml | 2 +- codegen/models/project_pythia/project_pythia.xml | 2 +- codegen/models/project_ratchet/project_ratchet.xml | 2 +- library/common/include/virgil/crypto/common/vsc_library.h | 2 +- .../include/virgil/crypto/foundation/vscf_library.h | 2 +- library/phe/include/virgil/crypto/phe/vsce_library.h | 2 +- library/pythia/include/virgil/crypto/pythia/vscp_library.h | 2 +- library/ratchet/include/virgil/crypto/ratchet/vscr_library.h | 2 +- wrappers/java/android/build.gradle | 2 +- wrappers/java/benchmark/pom.xml | 2 +- wrappers/java/common/pom.xml | 2 +- wrappers/java/foundation/pom.xml | 2 +- wrappers/java/phe/pom.xml | 2 +- wrappers/java/pom.xml | 2 +- wrappers/java/pythia/pom.xml | 2 +- wrappers/java/ratchet/pom.xml | 2 +- wrappers/php/phe/extension/vsce_phe_php.c | 2 +- wrappers/php/pythia/extension/vscp_pythia_php.c | 2 +- wrappers/python/setup.py | 2 +- wrappers/python/virgil_crypto_lib/__init__.py | 2 +- wrappers/wasm/package.json | 2 +- 27 files changed, 29 insertions(+), 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a7deea4a5..83dbf3f61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,7 @@ cmake_minimum_required(VERSION 3.11 FATAL_ERROR) -project(virgil_crypto VERSION 0.10.1 LANGUAGES C) +project(virgil_crypto VERSION 0.10.2 LANGUAGES C) # --------------------------------------------------------------------------- @@ -57,7 +57,7 @@ include("cmake/protobuf.cmake") # --------------------------------------------------------------------------- # Version options # --------------------------------------------------------------------------- -set(VIRGIL_CRYPTO_VERSION_LABEL "" CACHE STRING "Version label, i.e. beta, rc1.") +set(VIRGIL_CRYPTO_VERSION_LABEL "dev1" CACHE STRING "Version label, i.e. beta, rc1.") # --------------------------------------------------------------------------- # Build options diff --git a/VERSION b/VERSION index 571215736..95e4a375a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.10.1 +0.10.2-dev1 diff --git a/VSCCrypto.podspec b/VSCCrypto.podspec index 8c5c7a349..56dd77a42 100644 --- a/VSCCrypto.podspec +++ b/VSCCrypto.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = "VSCCrypto" - s.version = "0.10.1" + s.version = "0.10.2" s.license = { :type => "BSD", :file => "Carthage/LICENSE" } s.summary = "Contains basic c functions classes for creating key pairs, encrypting/decrypting data, signing data and verifying signatures." s.homepage = "https://github.com/VirgilSecurity/virgil-crypto-c" s.authors = { "Virgil Security" => "https://virgilsecurity.com/" } - s.source = { :http => "https://github.com/VirgilSecurity/virgil-crypto-c/releases/download/v0.10.1/VSCCrypto.framework.zip" } + s.source = { :http => "https://github.com/VirgilSecurity/virgil-crypto-c/releases/download/v0.10.2/VSCCrypto.framework.zip" } s.ios.deployment_target = "9.0" s.osx.deployment_target = "10.9" s.tvos.deployment_target = "9.0" diff --git a/codegen/main.xml b/codegen/main.xml index 73901825a..53264ff95 100644 --- a/codegen/main.xml +++ b/codegen/main.xml @@ -40,7 +40,7 @@ - + diff --git a/codegen/models/project_common/project_common.xml b/codegen/models/project_common/project_common.xml index 69bf600ca..ae1909f4b 100644 --- a/codegen/models/project_common/project_common.xml +++ b/codegen/models/project_common/project_common.xml @@ -9,7 +9,7 @@ wrappers="python" > - + Copyright (C) 2015-2019 Virgil Security, Inc. diff --git a/codegen/models/project_foundation/project_foundation.xml b/codegen/models/project_foundation/project_foundation.xml index 83b3ed060..aac84887c 100644 --- a/codegen/models/project_foundation/project_foundation.xml +++ b/codegen/models/project_foundation/project_foundation.xml @@ -9,7 +9,7 @@ wrappers="swift,java,python,wasm" > - + Copyright (C) 2015-2019 Virgil Security, Inc. diff --git a/codegen/models/project_phe/project_phe.xml b/codegen/models/project_phe/project_phe.xml index a05da1a05..66b4baff6 100644 --- a/codegen/models/project_phe/project_phe.xml +++ b/codegen/models/project_phe/project_phe.xml @@ -9,7 +9,7 @@ wrappers="java,python,wasm" > - + Copyright (C) 2015-2019 Virgil Security, Inc. diff --git a/codegen/models/project_pythia/project_pythia.xml b/codegen/models/project_pythia/project_pythia.xml index 1a864d10f..d25be4bae 100644 --- a/codegen/models/project_pythia/project_pythia.xml +++ b/codegen/models/project_pythia/project_pythia.xml @@ -9,7 +9,7 @@ wrappers="java,swift,python,wasm" > - + Copyright (C) 2015-2019 Virgil Security, Inc. diff --git a/codegen/models/project_ratchet/project_ratchet.xml b/codegen/models/project_ratchet/project_ratchet.xml index ba6a8b797..256ff53df 100644 --- a/codegen/models/project_ratchet/project_ratchet.xml +++ b/codegen/models/project_ratchet/project_ratchet.xml @@ -9,7 +9,7 @@ wrappers="java,swift,python,wasm" > - + Copyright (C) 2015-2019 Virgil Security, Inc. diff --git a/library/common/include/virgil/crypto/common/vsc_library.h b/library/common/include/virgil/crypto/common/vsc_library.h index fd88e9cab..7bdf9265f 100644 --- a/library/common/include/virgil/crypto/common/vsc_library.h +++ b/library/common/include/virgil/crypto/common/vsc_library.h @@ -116,7 +116,7 @@ extern "C" { #define VSC_VERSION_MINOR 10 -#define VSC_VERSION_PATCH 1 +#define VSC_VERSION_PATCH 2 #define VSC_VERSION_MAKE(major, minor, patch) ((major) * 10000 + (minor) * 100 + (patch)) diff --git a/library/foundation/include/virgil/crypto/foundation/vscf_library.h b/library/foundation/include/virgil/crypto/foundation/vscf_library.h index 81d25772c..3699a9d21 100644 --- a/library/foundation/include/virgil/crypto/foundation/vscf_library.h +++ b/library/foundation/include/virgil/crypto/foundation/vscf_library.h @@ -116,7 +116,7 @@ extern "C" { #define VSCF_VERSION_MINOR 10 -#define VSCF_VERSION_PATCH 1 +#define VSCF_VERSION_PATCH 2 #define VSCF_VERSION_MAKE(major, minor, patch) ((major) * 10000 + (minor) * 100 + (patch)) diff --git a/library/phe/include/virgil/crypto/phe/vsce_library.h b/library/phe/include/virgil/crypto/phe/vsce_library.h index ee3d3fcd0..d96ae5b78 100644 --- a/library/phe/include/virgil/crypto/phe/vsce_library.h +++ b/library/phe/include/virgil/crypto/phe/vsce_library.h @@ -116,7 +116,7 @@ extern "C" { #define VSCE_VERSION_MINOR 10 -#define VSCE_VERSION_PATCH 1 +#define VSCE_VERSION_PATCH 2 #define VSCE_VERSION_MAKE(major, minor, patch) ((major) * 10000 + (minor) * 100 + (patch)) diff --git a/library/pythia/include/virgil/crypto/pythia/vscp_library.h b/library/pythia/include/virgil/crypto/pythia/vscp_library.h index 37b97113a..b226df18d 100644 --- a/library/pythia/include/virgil/crypto/pythia/vscp_library.h +++ b/library/pythia/include/virgil/crypto/pythia/vscp_library.h @@ -116,7 +116,7 @@ extern "C" { #define VSCP_VERSION_MINOR 10 -#define VSCP_VERSION_PATCH 1 +#define VSCP_VERSION_PATCH 2 #define VSCP_VERSION_MAKE(major, minor, patch) ((major) * 10000 + (minor) * 100 + (patch)) diff --git a/library/ratchet/include/virgil/crypto/ratchet/vscr_library.h b/library/ratchet/include/virgil/crypto/ratchet/vscr_library.h index bd30520ad..3b53abb6b 100644 --- a/library/ratchet/include/virgil/crypto/ratchet/vscr_library.h +++ b/library/ratchet/include/virgil/crypto/ratchet/vscr_library.h @@ -116,7 +116,7 @@ extern "C" { #define VSCR_VERSION_MINOR 10 -#define VSCR_VERSION_PATCH 1 +#define VSCR_VERSION_PATCH 2 #define VSCR_VERSION_MAKE(major, minor, patch) ((major) * 10000 + (minor) * 100 + (patch)) diff --git a/wrappers/java/android/build.gradle b/wrappers/java/android/build.gradle index 3628c1e30..77cfdd7a8 100644 --- a/wrappers/java/android/build.gradle +++ b/wrappers/java/android/build.gradle @@ -21,7 +21,7 @@ allprojects { mavenLocal() } group "com.virgilsecurity.crypto" - version "0.10.1" + version "0.10.2-SNAPSHOT" def authentication_username = hasProperty('authentication_username') ? authentication_username : System.getenv('authentication_username') def authentication_password = hasProperty('authentication_password') ? authentication_password : System.getenv('authentication_password') diff --git a/wrappers/java/benchmark/pom.xml b/wrappers/java/benchmark/pom.xml index e84efd6fd..53bc22079 100644 --- a/wrappers/java/benchmark/pom.xml +++ b/wrappers/java/benchmark/pom.xml @@ -5,7 +5,7 @@ com.virgilsecurity.crypto parent - 0.10.1 + 0.10.2-SNAPSHOT benchmark diff --git a/wrappers/java/common/pom.xml b/wrappers/java/common/pom.xml index 0dddd4091..559e4210e 100755 --- a/wrappers/java/common/pom.xml +++ b/wrappers/java/common/pom.xml @@ -36,7 +36,7 @@ com.virgilsecurity.crypto parent - 0.10.1 + 0.10.2-SNAPSHOT jar common diff --git a/wrappers/java/foundation/pom.xml b/wrappers/java/foundation/pom.xml index 0f4aea893..286f76063 100755 --- a/wrappers/java/foundation/pom.xml +++ b/wrappers/java/foundation/pom.xml @@ -36,7 +36,7 @@ com.virgilsecurity.crypto parent - 0.10.1 + 0.10.2-SNAPSHOT foundation diff --git a/wrappers/java/phe/pom.xml b/wrappers/java/phe/pom.xml index 5a3bbe686..c5ba71d5d 100755 --- a/wrappers/java/phe/pom.xml +++ b/wrappers/java/phe/pom.xml @@ -36,7 +36,7 @@ com.virgilsecurity.crypto parent - 0.10.1 + 0.10.2-SNAPSHOT phe diff --git a/wrappers/java/pom.xml b/wrappers/java/pom.xml index df18a7ba4..86454a16d 100755 --- a/wrappers/java/pom.xml +++ b/wrappers/java/pom.xml @@ -36,7 +36,7 @@ com.virgilsecurity.crypto parent pom - 0.10.1 + 0.10.2-SNAPSHOT Virgil Security Crypto Library diff --git a/wrappers/java/pythia/pom.xml b/wrappers/java/pythia/pom.xml index a2d474dd1..3f212053c 100755 --- a/wrappers/java/pythia/pom.xml +++ b/wrappers/java/pythia/pom.xml @@ -36,7 +36,7 @@ com.virgilsecurity.crypto parent - 0.10.1 + 0.10.2-SNAPSHOT pythia diff --git a/wrappers/java/ratchet/pom.xml b/wrappers/java/ratchet/pom.xml index 69826cae8..6155eea2e 100755 --- a/wrappers/java/ratchet/pom.xml +++ b/wrappers/java/ratchet/pom.xml @@ -36,7 +36,7 @@ com.virgilsecurity.crypto parent - 0.10.1 + 0.10.2-SNAPSHOT ratchet diff --git a/wrappers/php/phe/extension/vsce_phe_php.c b/wrappers/php/phe/extension/vsce_phe_php.c index 66c3cb495..9de5cdada 100644 --- a/wrappers/php/phe/extension/vsce_phe_php.c +++ b/wrappers/php/phe/extension/vsce_phe_php.c @@ -51,7 +51,7 @@ // -------------------------------------------------------------------------- // Constants // -------------------------------------------------------------------------- -const char VSCE_PHE_PHP_VERSION[] = "0.10.1"; +const char VSCE_PHE_PHP_VERSION[] = "0.10.2"; const char VSCE_PHE_PHP_EXTNAME[] = "vsce_phe_php"; const char VSCE_PHE_CLIENT_PHP_RES_NAME[] = "vsce_phe_client_t"; diff --git a/wrappers/php/pythia/extension/vscp_pythia_php.c b/wrappers/php/pythia/extension/vscp_pythia_php.c index 0fd0847a9..8a5282326 100644 --- a/wrappers/php/pythia/extension/vscp_pythia_php.c +++ b/wrappers/php/pythia/extension/vscp_pythia_php.c @@ -48,7 +48,7 @@ // -------------------------------------------------------------------------- // Constants // -------------------------------------------------------------------------- -const char VSCP_PYTHIA_PHP_VERSION[] = "0.10.1"; +const char VSCP_PYTHIA_PHP_VERSION[] = "0.10.2"; const char VSCP_PYTHIA_PHP_EXTNAME[] = "vscp_pythia_php"; const char VSCP_PYTHIA_PHP_RES_NAME[] = "vscp_pythia_t"; diff --git a/wrappers/python/setup.py b/wrappers/python/setup.py index a92af8175..448acd313 100644 --- a/wrappers/python/setup.py +++ b/wrappers/python/setup.py @@ -62,7 +62,7 @@ def is_pure(self): author_email="support@virgilsecurity.com", url="https://virgilsecurity.com", classifiers=[ - "Development Status :: 5 - Production/Stable", + "Development Status :: 2 - Pre-Alpha", "License :: OSI Approved :: BSD License", "Natural Language :: English", "Intended Audience :: Developers", diff --git a/wrappers/python/virgil_crypto_lib/__init__.py b/wrappers/python/virgil_crypto_lib/__init__.py index cf504b18a..d5d4369c6 100644 --- a/wrappers/python/virgil_crypto_lib/__init__.py +++ b/wrappers/python/virgil_crypto_lib/__init__.py @@ -34,4 +34,4 @@ __author__ = "Virgil Security" -__version__ = "0.10.1" +__version__ = "0.10.2-dev1" diff --git a/wrappers/wasm/package.json b/wrappers/wasm/package.json index d6064f263..dfedb155c 100644 --- a/wrappers/wasm/package.json +++ b/wrappers/wasm/package.json @@ -1,6 +1,6 @@ { "name": "@virgilsecurity/crypto", - "version": "0.10.1", + "version": "0.10.2", "description": "Virgil Crypto C wrapper", "repository": "https://github.com/VirgilSecurity/virgil-crypto-c", "author": "Virgil Security Inc. ", From 958cb15cb410136992307f51011a17e6ab21d887 Mon Sep 17 00:00:00 2001 From: Oleksandr Deundiak Date: Thu, 5 Sep 2019 13:53:15 +0300 Subject: [PATCH 2/9] Added PHE Cipher additional data support --- .../models/project_phe/class_phe_cipher.xml | 57 ++++++++ .../models/project_phe/class_phe_common.xml | 3 + .../virgil/crypto/phe/vsce_phe_cipher.h | 14 ++ .../virgil/crypto/phe/vsce_phe_common.h | 6 +- library/phe/src/vsce_phe_cipher.c | 40 +++++- tests/phe/test_phe_cipher.c | 79 +++++++++++ wrappers/java/phe/jni/PheJNI.c | 70 +++++++++ wrappers/java/phe/jni/PheJNI.h | 4 + .../virgilsecurity/crypto/phe/PheCipher.java | 14 ++ .../virgilsecurity/crypto/phe/PheCommon.java | 7 + .../com/virgilsecurity/crypto/phe/PheJNI.java | 10 ++ .../phe/_c_bridge/_vsce_phe_cipher.py | 14 ++ .../phe/_c_bridge/_vsce_phe_common.py | 2 + .../python/virgil_crypto_lib/phe/cipher.py | 20 +++ .../python/virgil_crypto_lib/phe/common.py | 2 + wrappers/wasm/phe/exported_functions.json | 4 +- wrappers/wasm/phe/src/PheCipher.js | 134 ++++++++++++++++++ wrappers/wasm/phe/src/PheCommon.js | 11 ++ 18 files changed, 483 insertions(+), 8 deletions(-) diff --git a/codegen/models/project_phe/class_phe_cipher.xml b/codegen/models/project_phe/class_phe_cipher.xml index e92841240..cba7d4f85 100644 --- a/codegen/models/project_phe/class_phe_cipher.xml +++ b/codegen/models/project_phe/class_phe_cipher.xml @@ -95,4 +95,61 @@ + + Encrypts data (and authenticates additional data) using account key + + + Data to encrypt + + + + Data to authenticate + + + + Account key + + + + Encrypted data + + + + + + + + - vsce_error_AES_ERROR in case AES returned error + - vsce_error_RNG_ERROR in case rng failed + + + + + Decrypts data (and verifies additional data) using account key + + + Encrypted data + + + + Data to authenticate + + + + Account key + + + + Encrypted data + + + + + + + + - vsce_error_AES_ERROR in case AES returned error + + + diff --git a/codegen/models/project_phe/class_phe_common.xml b/codegen/models/project_phe/class_phe_common.xml index 21966bac6..aecba013d 100644 --- a/codegen/models/project_phe/class_phe_common.xml +++ b/codegen/models/project_phe/class_phe_common.xml @@ -29,4 +29,7 @@ Maximum data size to decrypt + + Maximum data to authenticate + diff --git a/library/phe/include/virgil/crypto/phe/vsce_phe_cipher.h b/library/phe/include/virgil/crypto/phe/vsce_phe_cipher.h index 4f8c1c902..2e2b4e118 100644 --- a/library/phe/include/virgil/crypto/phe/vsce_phe_cipher.h +++ b/library/phe/include/virgil/crypto/phe/vsce_phe_cipher.h @@ -195,6 +195,20 @@ VSCE_PUBLIC vsce_status_t vsce_phe_cipher_decrypt(vsce_phe_cipher_t *self, vsc_data_t cipher_text, vsc_data_t account_key, vsc_buffer_t *plain_text) VSCE_NODISCARD; +// +// Encrypts data (and authenticates additional data) using account key +// +VSCE_PUBLIC vsce_status_t +vsce_phe_cipher_auth_encrypt(vsce_phe_cipher_t *self, vsc_data_t plain_text, vsc_data_t additional_data, + vsc_data_t account_key, vsc_buffer_t *cipher_text) VSCE_NODISCARD; + +// +// Decrypts data (and verifies additional data) using account key +// +VSCE_PUBLIC vsce_status_t +vsce_phe_cipher_auth_decrypt(vsce_phe_cipher_t *self, vsc_data_t cipher_text, vsc_data_t additional_data, + vsc_data_t account_key, vsc_buffer_t *plain_text) VSCE_NODISCARD; + // -------------------------------------------------------------------------- // Generated section end. diff --git a/library/phe/include/virgil/crypto/phe/vsce_phe_common.h b/library/phe/include/virgil/crypto/phe/vsce_phe_common.h index cdb41b5de..45d835785 100644 --- a/library/phe/include/virgil/crypto/phe/vsce_phe_common.h +++ b/library/phe/include/virgil/crypto/phe/vsce_phe_common.h @@ -107,7 +107,11 @@ enum { // // Maximum data size to decrypt // - vsce_phe_common_PHE_MAX_DECRYPT_LEN = 1024 * 1024 + vsce_phe_common_PHE_MAX_DECRYPT_LEN = 1024 * 1024, + // + // Maximum data to authenticate + // + vsce_phe_common_PHE_MAX_AUTH_LEN = 1024 }; diff --git a/library/phe/src/vsce_phe_cipher.c b/library/phe/src/vsce_phe_cipher.c index 299567f8c..cd87f4e70 100644 --- a/library/phe/src/vsce_phe_cipher.c +++ b/library/phe/src/vsce_phe_cipher.c @@ -366,7 +366,31 @@ VSCE_PUBLIC vsce_status_t vsce_phe_cipher_encrypt( vsce_phe_cipher_t *self, vsc_data_t plain_text, vsc_data_t account_key, vsc_buffer_t *cipher_text) { + return vsce_phe_cipher_auth_encrypt(self, plain_text, vsc_data_empty(), account_key, cipher_text); +} + +// +// Decrypts data using account key +// +VSCE_PUBLIC vsce_status_t +vsce_phe_cipher_decrypt( + vsce_phe_cipher_t *self, vsc_data_t cipher_text, vsc_data_t account_key, vsc_buffer_t *plain_text) { + + return vsce_phe_cipher_auth_decrypt(self, cipher_text, vsc_data_empty(), account_key, plain_text); +} + +// +// Encrypts data (and authenticates additional data) using account key +// +VSCE_PUBLIC vsce_status_t +vsce_phe_cipher_auth_encrypt(vsce_phe_cipher_t *self, vsc_data_t plain_text, vsc_data_t additional_data, + vsc_data_t account_key, vsc_buffer_t *cipher_text) { + VSCE_ASSERT_PTR(self); + VSCE_ASSERT(vsc_data_is_valid(plain_text)); + VSCE_ASSERT(vsc_data_is_valid(additional_data)); + VSCE_ASSERT(vsc_data_is_valid(account_key)); + VSCE_ASSERT(vsc_buffer_is_valid(cipher_text)); VSCE_ASSERT(account_key.len == vsce_phe_common_PHE_ACCOUNT_KEY_LENGTH); VSCE_ASSERT(plain_text.len <= vsce_phe_common_PHE_MAX_ENCRYPT_LEN); VSCE_ASSERT(vsc_buffer_capacity(cipher_text) >= vsce_phe_cipher_encrypt_len(self, plain_text.len)); @@ -410,7 +434,7 @@ vsce_phe_cipher_encrypt( memcpy(vsc_buffer_unused_bytes(cipher_text), salt, sizeof(salt)); vsc_buffer_inc_used(cipher_text, sizeof(salt)); - f_status = vscf_aes256_gcm_encrypt(aes256_gcm, plain_text, cipher_text); + f_status = vscf_aes256_gcm_auth_encrypt(aes256_gcm, plain_text, additional_data, cipher_text, NULL); if (f_status != vscf_status_SUCCESS) { status = vsce_status_ERROR_AES_FAILED; @@ -429,13 +453,17 @@ vsce_phe_cipher_encrypt( } // -// Decrypts data using account key +// Decrypts data (and verifies additional data) using account key // VSCE_PUBLIC vsce_status_t -vsce_phe_cipher_decrypt( - vsce_phe_cipher_t *self, vsc_data_t cipher_text, vsc_data_t account_key, vsc_buffer_t *plain_text) { +vsce_phe_cipher_auth_decrypt(vsce_phe_cipher_t *self, vsc_data_t cipher_text, vsc_data_t additional_data, + vsc_data_t account_key, vsc_buffer_t *plain_text) { VSCE_ASSERT_PTR(self); + VSCE_ASSERT(vsc_data_is_valid(cipher_text)); + VSCE_ASSERT(vsc_data_is_valid(additional_data)); + VSCE_ASSERT(vsc_data_is_valid(account_key)); + VSCE_ASSERT(vsc_buffer_is_valid(plain_text)); VSCE_ASSERT(account_key.len == vsce_phe_common_PHE_ACCOUNT_KEY_LENGTH); VSCE_ASSERT(cipher_text.len <= vsce_phe_common_PHE_MAX_DECRYPT_LEN); VSCE_ASSERT(vsc_buffer_capacity(plain_text) >= vsce_phe_cipher_decrypt_len(self, cipher_text.len)); @@ -463,9 +491,9 @@ vsce_phe_cipher_decrypt( vscf_aes256_gcm_set_nonce( aes256_gcm, vsc_data_slice_end(vsc_buffer_data(&derived_secret_buf), 0, vsce_phe_cipher_NONCE_LEN)); - vscf_status_t f_status = vscf_aes256_gcm_decrypt(aes256_gcm, + vscf_status_t f_status = vscf_aes256_gcm_auth_decrypt(aes256_gcm, vsc_data_slice_beg(cipher_text, vsce_phe_cipher_SALT_LEN, cipher_text.len - vsce_phe_cipher_SALT_LEN), - plain_text); + additional_data, vsc_data_empty(), plain_text); if (f_status != vscf_status_SUCCESS) { status = vsce_status_ERROR_AES_FAILED; diff --git a/tests/phe/test_phe_cipher.c b/tests/phe/test_phe_cipher.c index de01cf6c2..1c05b9d04 100644 --- a/tests/phe/test_phe_cipher.c +++ b/tests/phe/test_phe_cipher.c @@ -138,6 +138,84 @@ test__encrypt_decrypt__random_data__should_match(void) { vsce_phe_cipher_destroy(&cipher2); } +void +test__auth_encrypt_decrypt__random_data__should_match(void) { + vsce_phe_cipher_t *cipher1, *cipher2; + + cipher1 = vsce_phe_cipher_new(); + TEST_ASSERT_EQUAL(vsce_status_SUCCESS, vsce_phe_cipher_setup_defaults(cipher1)); + + cipher2 = vsce_phe_cipher_new(); + TEST_ASSERT_EQUAL(vsce_status_SUCCESS, vsce_phe_cipher_setup_defaults(cipher2)); + + vscf_ctr_drbg_t *rng = vscf_ctr_drbg_new(); + TEST_ASSERT_EQUAL(vscf_status_SUCCESS, vscf_ctr_drbg_setup_defaults(rng)); + + for (int i = 0; i < 100; i++) { + vsc_buffer_t *account_key = vsc_buffer_new_with_capacity(vsce_phe_common_PHE_ACCOUNT_KEY_LENGTH); + + TEST_ASSERT_EQUAL( + vscf_status_SUCCESS, vscf_ctr_drbg_random(rng, vsce_phe_common_PHE_ACCOUNT_KEY_LENGTH, account_key)); + + byte data_len, addata_len; + + vsc_buffer_t *len_buf = vsc_buffer_new(); + vsc_buffer_use(len_buf, &data_len, sizeof(data_len)); + + TEST_ASSERT_EQUAL(vscf_status_SUCCESS, vscf_ctr_drbg_random(rng, sizeof(data_len), len_buf)); + + if (data_len == 0) { + data_len = 10; + } + + vsc_buffer_t *adlen_buf = vsc_buffer_new(); + vsc_buffer_use(adlen_buf, &addata_len, sizeof(addata_len)); + + TEST_ASSERT_EQUAL(vscf_status_SUCCESS, vscf_ctr_drbg_random(rng, sizeof(addata_len), adlen_buf)); + + if (addata_len == 0) { + addata_len = 10; + } + + vsc_buffer_t *plain_text = vsc_buffer_new_with_capacity(data_len); + vsc_buffer_t *addata = vsc_buffer_new_with_capacity(addata_len); + + TEST_ASSERT_EQUAL(vscf_status_SUCCESS, vscf_ctr_drbg_random(rng, data_len, plain_text)); + TEST_ASSERT_EQUAL(vscf_status_SUCCESS, vscf_ctr_drbg_random(rng, addata_len, addata)); + + vsc_buffer_t *cipher_text = vsc_buffer_new_with_capacity(vsce_phe_cipher_encrypt_len(cipher1, data_len)); + + TEST_ASSERT_EQUAL( + vsce_status_SUCCESS, vsce_phe_cipher_auth_encrypt(cipher1, vsc_buffer_data(plain_text), + vsc_buffer_data(addata), vsc_buffer_data(account_key), cipher_text)); + + vsc_buffer_t *plain_text2 = + vsc_buffer_new_with_capacity(vsce_phe_cipher_decrypt_len(cipher2, vsc_buffer_len(cipher_text))); + + TEST_ASSERT_EQUAL( + vsce_status_SUCCESS, vsce_phe_cipher_auth_decrypt(cipher2, vsc_buffer_data(cipher_text), + vsc_buffer_data(addata), vsc_buffer_data(account_key), plain_text2)); + + TEST_ASSERT_EQUAL(vsc_buffer_len(plain_text), vsc_buffer_len(plain_text2)); + + TEST_ASSERT_EQUAL_MEMORY( + vsc_buffer_bytes(plain_text), vsc_buffer_bytes(plain_text2), vsc_buffer_len(plain_text)); + + vsc_buffer_destroy(&account_key); + vsc_buffer_destroy(&len_buf); + vsc_buffer_destroy(&plain_text); + vsc_buffer_destroy(&addata); + vsc_buffer_destroy(&adlen_buf); + vsc_buffer_destroy(&cipher_text); + vsc_buffer_destroy(&plain_text2); + } + + vscf_ctr_drbg_destroy(&rng); + + vsce_phe_cipher_destroy(&cipher1); + vsce_phe_cipher_destroy(&cipher2); +} + #endif // TEST_DEPENDENCIES_AVAILABLE @@ -151,6 +229,7 @@ main(void) { #if TEST_DEPENDENCIES_AVAILABLE RUN_TEST(test__encrypt_decrypt__fixed_data__should_match); RUN_TEST(test__encrypt_decrypt__random_data__should_match); + RUN_TEST(test__auth_encrypt_decrypt__random_data__should_match); #else RUN_TEST(test__nothing__feature_disabled__must_be_ignored); #endif diff --git a/wrappers/java/phe/jni/PheJNI.c b/wrappers/java/phe/jni/PheJNI.c index 83d44b1f6..79e1a2711 100644 --- a/wrappers/java/phe/jni/PheJNI.c +++ b/wrappers/java/phe/jni/PheJNI.c @@ -693,3 +693,73 @@ JNIEXPORT jbyteArray JNICALL Java_com_virgilsecurity_crypto_phe_PheJNI_pheCipher return ret; } +JNIEXPORT jbyteArray JNICALL Java_com_virgilsecurity_crypto_phe_PheJNI_pheCipher_1authEncrypt (JNIEnv *jenv, jobject jobj, jlong c_ctx, jbyteArray jplainText, jbyteArray jadditionalData, jbyteArray jaccountKey) { + // Cast class context + vsce_phe_cipher_t /*2*/* phe_cipher_ctx = *(vsce_phe_cipher_t /*2*/**) &c_ctx; + + // Wrap input data + byte* plain_text_arr = (byte*) (*jenv)->GetByteArrayElements(jenv, jplainText, NULL); + vsc_data_t plain_text = vsc_data(plain_text_arr, (*jenv)->GetArrayLength(jenv, jplainText)); + + byte* additional_data_arr = (byte*) (*jenv)->GetByteArrayElements(jenv, jadditionalData, NULL); + vsc_data_t additional_data = vsc_data(additional_data_arr, (*jenv)->GetArrayLength(jenv, jadditionalData)); + + byte* account_key_arr = (byte*) (*jenv)->GetByteArrayElements(jenv, jaccountKey, NULL); + vsc_data_t account_key = vsc_data(account_key_arr, (*jenv)->GetArrayLength(jenv, jaccountKey)); + + vsc_buffer_t *cipher_text = vsc_buffer_new_with_capacity(vsce_phe_cipher_encrypt_len((vsce_phe_cipher_t /*2*/ *) c_ctx /*3*/, plain_text.len/*a*/)); + + vsce_status_t status = vsce_phe_cipher_auth_encrypt(phe_cipher_ctx /*a1*/, plain_text /*a3*/, additional_data /*a3*/, account_key /*a3*/, cipher_text /*a3*/); + if (status != vsce_status_SUCCESS) { + throwPheException(jenv, jobj, status); + return NULL; + } + jbyteArray ret = (*jenv)->NewByteArray(jenv, vsc_buffer_len(cipher_text)); + (*jenv)->SetByteArrayRegion (jenv, ret, 0, vsc_buffer_len(cipher_text), (jbyte*) vsc_buffer_bytes(cipher_text)); + // Free resources + (*jenv)->ReleaseByteArrayElements(jenv, jplainText, (jbyte*) plain_text_arr, 0); + + (*jenv)->ReleaseByteArrayElements(jenv, jadditionalData, (jbyte*) additional_data_arr, 0); + + (*jenv)->ReleaseByteArrayElements(jenv, jaccountKey, (jbyte*) account_key_arr, 0); + + vsc_buffer_delete(cipher_text); + + return ret; +} + +JNIEXPORT jbyteArray JNICALL Java_com_virgilsecurity_crypto_phe_PheJNI_pheCipher_1authDecrypt (JNIEnv *jenv, jobject jobj, jlong c_ctx, jbyteArray jcipherText, jbyteArray jadditionalData, jbyteArray jaccountKey) { + // Cast class context + vsce_phe_cipher_t /*2*/* phe_cipher_ctx = *(vsce_phe_cipher_t /*2*/**) &c_ctx; + + // Wrap input data + byte* cipher_text_arr = (byte*) (*jenv)->GetByteArrayElements(jenv, jcipherText, NULL); + vsc_data_t cipher_text = vsc_data(cipher_text_arr, (*jenv)->GetArrayLength(jenv, jcipherText)); + + byte* additional_data_arr = (byte*) (*jenv)->GetByteArrayElements(jenv, jadditionalData, NULL); + vsc_data_t additional_data = vsc_data(additional_data_arr, (*jenv)->GetArrayLength(jenv, jadditionalData)); + + byte* account_key_arr = (byte*) (*jenv)->GetByteArrayElements(jenv, jaccountKey, NULL); + vsc_data_t account_key = vsc_data(account_key_arr, (*jenv)->GetArrayLength(jenv, jaccountKey)); + + vsc_buffer_t *plain_text = vsc_buffer_new_with_capacity(vsce_phe_cipher_decrypt_len((vsce_phe_cipher_t /*2*/ *) c_ctx /*3*/, cipher_text.len/*a*/)); + + vsce_status_t status = vsce_phe_cipher_auth_decrypt(phe_cipher_ctx /*a1*/, cipher_text /*a3*/, additional_data /*a3*/, account_key /*a3*/, plain_text /*a3*/); + if (status != vsce_status_SUCCESS) { + throwPheException(jenv, jobj, status); + return NULL; + } + jbyteArray ret = (*jenv)->NewByteArray(jenv, vsc_buffer_len(plain_text)); + (*jenv)->SetByteArrayRegion (jenv, ret, 0, vsc_buffer_len(plain_text), (jbyte*) vsc_buffer_bytes(plain_text)); + // Free resources + (*jenv)->ReleaseByteArrayElements(jenv, jcipherText, (jbyte*) cipher_text_arr, 0); + + (*jenv)->ReleaseByteArrayElements(jenv, jadditionalData, (jbyte*) additional_data_arr, 0); + + (*jenv)->ReleaseByteArrayElements(jenv, jaccountKey, (jbyte*) account_key_arr, 0); + + vsc_buffer_delete(plain_text); + + return ret; +} + diff --git a/wrappers/java/phe/jni/PheJNI.h b/wrappers/java/phe/jni/PheJNI.h index fabd70a79..8512bcae0 100644 --- a/wrappers/java/phe/jni/PheJNI.h +++ b/wrappers/java/phe/jni/PheJNI.h @@ -109,6 +109,10 @@ JNIEXPORT jbyteArray JNICALL Java_com_virgilsecurity_crypto_phe_PheJNI_pheCipher JNIEXPORT jbyteArray JNICALL Java_com_virgilsecurity_crypto_phe_PheJNI_pheCipher_1decrypt (JNIEnv *, jobject, jlong, jbyteArray, jbyteArray); +JNIEXPORT jbyteArray JNICALL Java_com_virgilsecurity_crypto_phe_PheJNI_pheCipher_1authEncrypt (JNIEnv *, jobject, jlong, jbyteArray, jbyteArray, jbyteArray); + +JNIEXPORT jbyteArray JNICALL Java_com_virgilsecurity_crypto_phe_PheJNI_pheCipher_1authDecrypt (JNIEnv *, jobject, jlong, jbyteArray, jbyteArray, jbyteArray); + #ifdef __cplusplus } #endif diff --git a/wrappers/java/phe/src/main/java/com/virgilsecurity/crypto/phe/PheCipher.java b/wrappers/java/phe/src/main/java/com/virgilsecurity/crypto/phe/PheCipher.java index 445d8fc00..ae2f632e9 100644 --- a/wrappers/java/phe/src/main/java/com/virgilsecurity/crypto/phe/PheCipher.java +++ b/wrappers/java/phe/src/main/java/com/virgilsecurity/crypto/phe/PheCipher.java @@ -124,5 +124,19 @@ public byte[] encrypt(byte[] plainText, byte[] accountKey) throws PheException { public byte[] decrypt(byte[] cipherText, byte[] accountKey) throws PheException { return PheJNI.INSTANCE.pheCipher_decrypt(this.cCtx, cipherText, accountKey); } + + /* + * Encrypts data (and authenticates additional data) using account key + */ + public byte[] authEncrypt(byte[] plainText, byte[] additionalData, byte[] accountKey) throws PheException { + return PheJNI.INSTANCE.pheCipher_authEncrypt(this.cCtx, plainText, additionalData, accountKey); + } + + /* + * Decrypts data (and verifies additional data) using account key + */ + public byte[] authDecrypt(byte[] cipherText, byte[] additionalData, byte[] accountKey) throws PheException { + return PheJNI.INSTANCE.pheCipher_authDecrypt(this.cCtx, cipherText, additionalData, accountKey); + } } diff --git a/wrappers/java/phe/src/main/java/com/virgilsecurity/crypto/phe/PheCommon.java b/wrappers/java/phe/src/main/java/com/virgilsecurity/crypto/phe/PheCommon.java index d4e9d78b7..c0a0afaa8 100644 --- a/wrappers/java/phe/src/main/java/com/virgilsecurity/crypto/phe/PheCommon.java +++ b/wrappers/java/phe/src/main/java/com/virgilsecurity/crypto/phe/PheCommon.java @@ -109,5 +109,12 @@ public int getPheMaxEncryptLen() { public int getPheMaxDecryptLen() { return 1024 * 1024; } + + /* + * Maximum data to authenticate + */ + public int getPheMaxAuthLen() { + return 1024; + } } diff --git a/wrappers/java/phe/src/main/java/com/virgilsecurity/crypto/phe/PheJNI.java b/wrappers/java/phe/src/main/java/com/virgilsecurity/crypto/phe/PheJNI.java index f49c33c7f..7914781f0 100644 --- a/wrappers/java/phe/src/main/java/com/virgilsecurity/crypto/phe/PheJNI.java +++ b/wrappers/java/phe/src/main/java/com/virgilsecurity/crypto/phe/PheJNI.java @@ -204,5 +204,15 @@ private PheJNI() { * Decrypts data using account key */ public native byte[] pheCipher_decrypt(long cCtx, byte[] cipherText, byte[] accountKey) throws PheException; + + /* + * Encrypts data (and authenticates additional data) using account key + */ + public native byte[] pheCipher_authEncrypt(long cCtx, byte[] plainText, byte[] additionalData, byte[] accountKey) throws PheException; + + /* + * Decrypts data (and verifies additional data) using account key + */ + public native byte[] pheCipher_authDecrypt(long cCtx, byte[] cipherText, byte[] additionalData, byte[] accountKey) throws PheException; } diff --git a/wrappers/python/virgil_crypto_lib/phe/_c_bridge/_vsce_phe_cipher.py b/wrappers/python/virgil_crypto_lib/phe/_c_bridge/_vsce_phe_cipher.py index c8caf5a1a..0a024c61e 100644 --- a/wrappers/python/virgil_crypto_lib/phe/_c_bridge/_vsce_phe_cipher.py +++ b/wrappers/python/virgil_crypto_lib/phe/_c_bridge/_vsce_phe_cipher.py @@ -111,6 +111,20 @@ def vsce_phe_cipher_decrypt(self, ctx, cipher_text, account_key, plain_text): vsce_phe_cipher_decrypt.restype = c_int return vsce_phe_cipher_decrypt(ctx, cipher_text, account_key, plain_text) + def vsce_phe_cipher_auth_encrypt(self, ctx, plain_text, additional_data, account_key, cipher_text): + """Encrypts data (and authenticates additional data) using account key""" + vsce_phe_cipher_auth_encrypt = self._lib.vsce_phe_cipher_auth_encrypt + vsce_phe_cipher_auth_encrypt.argtypes = [POINTER(vsce_phe_cipher_t), vsc_data_t, vsc_data_t, vsc_data_t, POINTER(vsc_buffer_t)] + vsce_phe_cipher_auth_encrypt.restype = c_int + return vsce_phe_cipher_auth_encrypt(ctx, plain_text, additional_data, account_key, cipher_text) + + def vsce_phe_cipher_auth_decrypt(self, ctx, cipher_text, additional_data, account_key, plain_text): + """Decrypts data (and verifies additional data) using account key""" + vsce_phe_cipher_auth_decrypt = self._lib.vsce_phe_cipher_auth_decrypt + vsce_phe_cipher_auth_decrypt.argtypes = [POINTER(vsce_phe_cipher_t), vsc_data_t, vsc_data_t, vsc_data_t, POINTER(vsc_buffer_t)] + vsce_phe_cipher_auth_decrypt.restype = c_int + return vsce_phe_cipher_auth_decrypt(ctx, cipher_text, additional_data, account_key, plain_text) + def vsce_phe_cipher_shallow_copy(self, ctx): vsce_phe_cipher_shallow_copy = self._lib.vsce_phe_cipher_shallow_copy vsce_phe_cipher_shallow_copy.argtypes = [POINTER(vsce_phe_cipher_t)] diff --git a/wrappers/python/virgil_crypto_lib/phe/_c_bridge/_vsce_phe_common.py b/wrappers/python/virgil_crypto_lib/phe/_c_bridge/_vsce_phe_common.py index 3bd156da8..70b7c1864 100644 --- a/wrappers/python/virgil_crypto_lib/phe/_c_bridge/_vsce_phe_common.py +++ b/wrappers/python/virgil_crypto_lib/phe/_c_bridge/_vsce_phe_common.py @@ -59,3 +59,5 @@ class VscePheCommon(object): PHE_MAX_ENCRYPT_LEN = 1024 * 1024 - 64 # Maximum data size to decrypt PHE_MAX_DECRYPT_LEN = 1024 * 1024 + # Maximum data to authenticate + PHE_MAX_AUTH_LEN = 1024 diff --git a/wrappers/python/virgil_crypto_lib/phe/cipher.py b/wrappers/python/virgil_crypto_lib/phe/cipher.py index f023f14e8..ba96c0885 100644 --- a/wrappers/python/virgil_crypto_lib/phe/cipher.py +++ b/wrappers/python/virgil_crypto_lib/phe/cipher.py @@ -94,6 +94,26 @@ def decrypt(self, cipher_text, account_key): VsceStatus.handle_status(status) return plain_text.get_bytes() + def auth_encrypt(self, plain_text, additional_data, account_key): + """Encrypts data (and authenticates additional data) using account key""" + d_plain_text = Data(plain_text) + d_additional_data = Data(additional_data) + d_account_key = Data(account_key) + cipher_text = Buffer(self.encrypt_len(plain_text_len=len(plain_text))) + status = self._lib_vsce_phe_cipher.vsce_phe_cipher_auth_encrypt(self.ctx, d_plain_text.data, d_additional_data.data, d_account_key.data, cipher_text.c_buffer) + VsceStatus.handle_status(status) + return cipher_text.get_bytes() + + def auth_decrypt(self, cipher_text, additional_data, account_key): + """Decrypts data (and verifies additional data) using account key""" + d_cipher_text = Data(cipher_text) + d_additional_data = Data(additional_data) + d_account_key = Data(account_key) + plain_text = Buffer(self.decrypt_len(cipher_text_len=len(cipher_text))) + status = self._lib_vsce_phe_cipher.vsce_phe_cipher_auth_decrypt(self.ctx, d_cipher_text.data, d_additional_data.data, d_account_key.data, plain_text.c_buffer) + VsceStatus.handle_status(status) + return plain_text.get_bytes() + @classmethod def take_c_ctx(cls, c_ctx): inst = cls.__new__(cls) diff --git a/wrappers/python/virgil_crypto_lib/phe/common.py b/wrappers/python/virgil_crypto_lib/phe/common.py index 2fa66cad7..2d3dd13ec 100644 --- a/wrappers/python/virgil_crypto_lib/phe/common.py +++ b/wrappers/python/virgil_crypto_lib/phe/common.py @@ -58,3 +58,5 @@ class Common(object): PHE_MAX_ENCRYPT_LEN = 1024 * 1024 - 64 # Maximum data size to decrypt PHE_MAX_DECRYPT_LEN = 1024 * 1024 + # Maximum data to authenticate + PHE_MAX_AUTH_LEN = 1024 diff --git a/wrappers/wasm/phe/exported_functions.json b/wrappers/wasm/phe/exported_functions.json index d22205761..3ad0c87fc 100644 --- a/wrappers/wasm/phe/exported_functions.json +++ b/wrappers/wasm/phe/exported_functions.json @@ -108,5 +108,7 @@ "_vsce_phe_cipher_encrypt_len", "_vsce_phe_cipher_decrypt_len", "_vsce_phe_cipher_encrypt", - "_vsce_phe_cipher_decrypt" + "_vsce_phe_cipher_decrypt", + "_vsce_phe_cipher_auth_encrypt", + "_vsce_phe_cipher_auth_decrypt" ] diff --git a/wrappers/wasm/phe/src/PheCipher.js b/wrappers/wasm/phe/src/PheCipher.js index 3ea06b2a7..b7afff063 100644 --- a/wrappers/wasm/phe/src/PheCipher.js +++ b/wrappers/wasm/phe/src/PheCipher.js @@ -235,6 +235,140 @@ const initPheCipher = (Module, modules) => { Module._vsc_buffer_delete(plainTextCtxPtr); } } + + /** + * Encrypts data (and authenticates additional data) using account key + */ + authEncrypt(plainText, additionalData, accountKey) { + precondition.ensureNotNull('this.ctxPtr', this.ctxPtr); + precondition.ensureByteArray('plainText', plainText); + precondition.ensureByteArray('additionalData', additionalData); + precondition.ensureByteArray('accountKey', accountKey); + + // Copy bytes from JS memory to the WASM memory. + const plainTextSize = plainText.length * plainText.BYTES_PER_ELEMENT; + const plainTextPtr = Module._malloc(plainTextSize); + Module.HEAP8.set(plainText, plainTextPtr); + + // Create C structure vsc_data_t. + const plainTextCtxSize = Module._vsc_data_ctx_size(); + const plainTextCtxPtr = Module._malloc(plainTextCtxSize); + + // Point created vsc_data_t object to the copied bytes. + Module._vsc_data(plainTextCtxPtr, plainTextPtr, plainTextSize); + + // Copy bytes from JS memory to the WASM memory. + const additionalDataSize = additionalData.length * additionalData.BYTES_PER_ELEMENT; + const additionalDataPtr = Module._malloc(additionalDataSize); + Module.HEAP8.set(additionalData, additionalDataPtr); + + // Create C structure vsc_data_t. + const additionalDataCtxSize = Module._vsc_data_ctx_size(); + const additionalDataCtxPtr = Module._malloc(additionalDataCtxSize); + + // Point created vsc_data_t object to the copied bytes. + Module._vsc_data(additionalDataCtxPtr, additionalDataPtr, additionalDataSize); + + // Copy bytes from JS memory to the WASM memory. + const accountKeySize = accountKey.length * accountKey.BYTES_PER_ELEMENT; + const accountKeyPtr = Module._malloc(accountKeySize); + Module.HEAP8.set(accountKey, accountKeyPtr); + + // Create C structure vsc_data_t. + const accountKeyCtxSize = Module._vsc_data_ctx_size(); + const accountKeyCtxPtr = Module._malloc(accountKeyCtxSize); + + // Point created vsc_data_t object to the copied bytes. + Module._vsc_data(accountKeyCtxPtr, accountKeyPtr, accountKeySize); + + const cipherTextCapacity = this.encryptLen(plainText.length); + const cipherTextCtxPtr = Module._vsc_buffer_new_with_capacity(cipherTextCapacity); + + try { + const proxyResult = Module._vsce_phe_cipher_auth_encrypt(this.ctxPtr, plainTextCtxPtr, additionalDataCtxPtr, accountKeyCtxPtr, cipherTextCtxPtr); + modules.PheError.handleStatusCode(proxyResult); + + const cipherTextPtr = Module._vsc_buffer_bytes(cipherTextCtxPtr); + const cipherTextPtrLen = Module._vsc_buffer_len(cipherTextCtxPtr); + const cipherText = Module.HEAPU8.slice(cipherTextPtr, cipherTextPtr + cipherTextPtrLen); + return cipherText; + } finally { + Module._free(plainTextPtr); + Module._free(plainTextCtxPtr); + Module._free(additionalDataPtr); + Module._free(additionalDataCtxPtr); + Module._free(accountKeyPtr); + Module._free(accountKeyCtxPtr); + Module._vsc_buffer_delete(cipherTextCtxPtr); + } + } + + /** + * Decrypts data (and verifies additional data) using account key + */ + authDecrypt(cipherText, additionalData, accountKey) { + precondition.ensureNotNull('this.ctxPtr', this.ctxPtr); + precondition.ensureByteArray('cipherText', cipherText); + precondition.ensureByteArray('additionalData', additionalData); + precondition.ensureByteArray('accountKey', accountKey); + + // Copy bytes from JS memory to the WASM memory. + const cipherTextSize = cipherText.length * cipherText.BYTES_PER_ELEMENT; + const cipherTextPtr = Module._malloc(cipherTextSize); + Module.HEAP8.set(cipherText, cipherTextPtr); + + // Create C structure vsc_data_t. + const cipherTextCtxSize = Module._vsc_data_ctx_size(); + const cipherTextCtxPtr = Module._malloc(cipherTextCtxSize); + + // Point created vsc_data_t object to the copied bytes. + Module._vsc_data(cipherTextCtxPtr, cipherTextPtr, cipherTextSize); + + // Copy bytes from JS memory to the WASM memory. + const additionalDataSize = additionalData.length * additionalData.BYTES_PER_ELEMENT; + const additionalDataPtr = Module._malloc(additionalDataSize); + Module.HEAP8.set(additionalData, additionalDataPtr); + + // Create C structure vsc_data_t. + const additionalDataCtxSize = Module._vsc_data_ctx_size(); + const additionalDataCtxPtr = Module._malloc(additionalDataCtxSize); + + // Point created vsc_data_t object to the copied bytes. + Module._vsc_data(additionalDataCtxPtr, additionalDataPtr, additionalDataSize); + + // Copy bytes from JS memory to the WASM memory. + const accountKeySize = accountKey.length * accountKey.BYTES_PER_ELEMENT; + const accountKeyPtr = Module._malloc(accountKeySize); + Module.HEAP8.set(accountKey, accountKeyPtr); + + // Create C structure vsc_data_t. + const accountKeyCtxSize = Module._vsc_data_ctx_size(); + const accountKeyCtxPtr = Module._malloc(accountKeyCtxSize); + + // Point created vsc_data_t object to the copied bytes. + Module._vsc_data(accountKeyCtxPtr, accountKeyPtr, accountKeySize); + + const plainTextCapacity = this.decryptLen(cipherText.length); + const plainTextCtxPtr = Module._vsc_buffer_new_with_capacity(plainTextCapacity); + + try { + const proxyResult = Module._vsce_phe_cipher_auth_decrypt(this.ctxPtr, cipherTextCtxPtr, additionalDataCtxPtr, accountKeyCtxPtr, plainTextCtxPtr); + modules.PheError.handleStatusCode(proxyResult); + + const plainTextPtr = Module._vsc_buffer_bytes(plainTextCtxPtr); + const plainTextPtrLen = Module._vsc_buffer_len(plainTextCtxPtr); + const plainText = Module.HEAPU8.slice(plainTextPtr, plainTextPtr + plainTextPtrLen); + return plainText; + } finally { + Module._free(cipherTextPtr); + Module._free(cipherTextCtxPtr); + Module._free(additionalDataPtr); + Module._free(additionalDataCtxPtr); + Module._free(accountKeyPtr); + Module._free(accountKeyCtxPtr); + Module._vsc_buffer_delete(plainTextCtxPtr); + } + } } return PheCipher; diff --git a/wrappers/wasm/phe/src/PheCommon.js b/wrappers/wasm/phe/src/PheCommon.js index aa24b5f1e..268e20037 100644 --- a/wrappers/wasm/phe/src/PheCommon.js +++ b/wrappers/wasm/phe/src/PheCommon.js @@ -149,6 +149,17 @@ const initPheCommon = (Module, modules) => { get PHE_MAX_DECRYPT_LEN() { return PheCommon.PHE_MAX_DECRYPT_LEN; } + + /** + * Maximum data to authenticate + */ + static get PHE_MAX_AUTH_LEN() { + return 1024; + } + + get PHE_MAX_AUTH_LEN() { + return PheCommon.PHE_MAX_AUTH_LEN; + } } return PheCommon; From 6b37d4f4f356ce1bdb791658216802486e79db9b Mon Sep 17 00:00:00 2001 From: Andrii Iakovenko Date: Thu, 5 Sep 2019 19:59:29 +0300 Subject: [PATCH 3/9] Run java benchmark with a profile only --- wrappers/java/README.md | 2 +- wrappers/java/pom.xml | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/wrappers/java/README.md b/wrappers/java/README.md index 3ec39e41f..9345ac553 100644 --- a/wrappers/java/README.md +++ b/wrappers/java/README.md @@ -42,7 +42,7 @@ mvn clean package Build artifacts with a command ```bash -mvn clean install +mvn clean package -Pall,benchmark ``` A JAR file with benchmarks and all dependencies will be build. You can find it at `benchmark/target/benchmark.jar`. diff --git a/wrappers/java/pom.xml b/wrappers/java/pom.xml index 86454a16d..a8a606625 100755 --- a/wrappers/java/pom.xml +++ b/wrappers/java/pom.xml @@ -87,7 +87,6 @@ common - benchmark @@ -225,6 +224,12 @@ ratchet + + benchmark + + benchmark + + foundation From 7700485625c4af4c6eb2b3ac790254d3cebf470e Mon Sep 17 00:00:00 2001 From: SergeySeroshtan Date: Fri, 6 Sep 2019 21:31:26 +0300 Subject: [PATCH 4/9] Implement support for managing recipients within MessageInfo (lib, foundation) --- .../class_key_recipient_info_list.xml | 12 + .../project_foundation/class_message_info.xml | 7 + .../class_message_info_editor.xml | 79 +++ .../class_recipient_cipher.xml | 2 +- .../project_foundation/project_foundation.xml | 1 + library/common/src/vsc_buffer.c | 3 +- library/foundation/definitions.cmake | 1 + library/foundation/features.cmake | 101 ++++ .../private/vscf_foundation_private.h | 1 + .../private/vscf_message_info_editor_defs.h | 123 ++++ .../foundation/vscf_foundation_public.h | 1 + .../foundation/vscf_key_recipient_info_list.h | 12 + .../crypto/foundation/vscf_message_info.h | 6 + .../foundation/vscf_message_info_editor.h | 220 ++++++++ .../crypto/foundation/vscf_platform.h.in | 4 + .../crypto/foundation/vscf_recipient_cipher.h | 2 +- library/foundation/module.modulemap | 1 + library/foundation/sources.cmake | 9 + .../src/vscf_key_recipient_info_list.c | 26 + library/foundation/src/vscf_message_info.c | 12 + .../foundation/src/vscf_message_info_editor.c | 534 ++++++++++++++++++ .../src/vscf_message_info_editor_defs.c | 70 +++ .../foundation/src/vscf_recipient_cipher.c | 2 +- tests/foundation/CMakeLists.txt | 1 + tests/foundation/data/CMakeLists.txt | 2 + .../data/include/test_data_message_info.h | 47 ++ .../data/src/test_data_message_info.c | 491 ++++++++++++++++ tests/foundation/test_message_info_editor.c | 266 +++++++++ wrappers/java/foundation/jni/FoundationJNI.c | 144 +++++ wrappers/java/foundation/jni/FoundationJNI.h | 20 + .../crypto/foundation/FoundationJNI.java | 46 +- .../crypto/foundation/MessageInfoEditor.java | 132 +++++ .../crypto/foundation/RecipientCipher.java | 2 +- .../virgil_crypto_lib/foundation/__init__.py | 1 + .../foundation/_c_bridge/__init__.py | 2 + .../_c_bridge/_vscf_message_info_editor.py | 134 +++++ .../_c_bridge/_vscf_recipient_cipher.py | 2 +- .../foundation/message_info_editor.py | 117 ++++ .../foundation/recipient_cipher.py | 2 +- .../MessageInfoEditor.swift | 152 +++++ .../RecipientCipher.swift | 2 +- .../wasm/foundation/exported_functions.json | 12 + .../wasm/foundation/src/MessageInfoEditor.js | 264 +++++++++ .../wasm/foundation/src/RecipientCipher.js | 2 +- wrappers/wasm/foundation/src/asmjs.js | 2 + wrappers/wasm/foundation/src/index.js | 2 + 46 files changed, 3064 insertions(+), 10 deletions(-) create mode 100644 codegen/models/project_foundation/class_message_info_editor.xml create mode 100644 library/foundation/include/virgil/crypto/foundation/private/vscf_message_info_editor_defs.h create mode 100644 library/foundation/include/virgil/crypto/foundation/vscf_message_info_editor.h create mode 100644 library/foundation/src/vscf_message_info_editor.c create mode 100644 library/foundation/src/vscf_message_info_editor_defs.c create mode 100644 tests/foundation/data/include/test_data_message_info.h create mode 100644 tests/foundation/data/src/test_data_message_info.c create mode 100644 tests/foundation/test_message_info_editor.c create mode 100644 wrappers/java/foundation/src/main/java/com/virgilsecurity/crypto/foundation/MessageInfoEditor.java create mode 100644 wrappers/python/virgil_crypto_lib/foundation/_c_bridge/_vscf_message_info_editor.py create mode 100644 wrappers/python/virgil_crypto_lib/foundation/message_info_editor.py create mode 100644 wrappers/swift/VirgilCrypto/VirgilCryptoFoundation/MessageInfoEditor.swift create mode 100644 wrappers/wasm/foundation/src/MessageInfoEditor.js diff --git a/codegen/models/project_foundation/class_key_recipient_info_list.xml b/codegen/models/project_foundation/class_key_recipient_info_list.xml index 3b7bfab5e..a0b456e0d 100644 --- a/codegen/models/project_foundation/class_key_recipient_info_list.xml +++ b/codegen/models/project_foundation/class_key_recipient_info_list.xml @@ -13,6 +13,11 @@ + + Remove current node. + + + Return true if given list has item. @@ -41,6 +46,13 @@ + + Return next list node if exists, or NULL otherwise. + + + + + Return true if list has previous item. diff --git a/codegen/models/project_foundation/class_message_info.xml b/codegen/models/project_foundation/class_message_info.xml index 7b09594ed..469fc8dc6 100644 --- a/codegen/models/project_foundation/class_message_info.xml +++ b/codegen/models/project_foundation/class_message_info.xml @@ -43,6 +43,13 @@ + + Return list with a "key recipient info" elements. + + + + + Return list with a "password recipient info" elements. diff --git a/codegen/models/project_foundation/class_message_info_editor.xml b/codegen/models/project_foundation/class_message_info_editor.xml new file mode 100644 index 000000000..ca8e4a7e7 --- /dev/null +++ b/codegen/models/project_foundation/class_message_info_editor.xml @@ -0,0 +1,79 @@ + + Add and/or remove recipients and it's paramteres within message info. + + Usage: + 1. Unpack binary message info that was obtained from RecipientCipher. + 2. Add and/or remove key recipients. + 3. Pack MessagInfo to the binary data. + + + + + + + + + + + + + + + + + + + + Set depenencies to it's defaults. + + + + + + Unpack serialized message info. + + + + + + + + + + Add recipient defined with id and public key. + + + + + + + + + Remove recipient with a given id. + Return false if recipient with given id was not found. + + + + + + + + Remove all existent recipients. + + + + Return length of serialized message info. + Actual length can be obtained right after applying changes. + + + + + + Return serialized message info. + Precondition: this method can be called after "apply". + + + + + + diff --git a/codegen/models/project_foundation/class_recipient_cipher.xml b/codegen/models/project_foundation/class_recipient_cipher.xml index 19da9cc0a..bdb96462c 100644 --- a/codegen/models/project_foundation/class_recipient_cipher.xml +++ b/codegen/models/project_foundation/class_recipient_cipher.xml @@ -50,7 +50,7 @@ Return buffer length required to hold message info returned by the - "start encryption" method. + "pack message info" method. Precondition: all recipients and custom parameters should be set. diff --git a/codegen/models/project_foundation/project_foundation.xml b/codegen/models/project_foundation/project_foundation.xml index aac84887c..db31b00d3 100644 --- a/codegen/models/project_foundation/project_foundation.xml +++ b/codegen/models/project_foundation/project_foundation.xml @@ -139,6 +139,7 @@ + diff --git a/library/common/src/vsc_buffer.c b/library/common/src/vsc_buffer.c index 7020a73af..3fe300c0e 100644 --- a/library/common/src/vsc_buffer.c +++ b/library/common/src/vsc_buffer.c @@ -433,6 +433,7 @@ vsc_buffer_alloc(vsc_buffer_t *self, size_t capacity) { self->capacity = capacity; self->len = 0; self->bytes_dealloc_cb = vsc_dealloc; + self->is_owner = true; } // @@ -453,7 +454,7 @@ vsc_buffer_release(vsc_buffer_t *self) { self->bytes = NULL; self->bytes_dealloc_cb = NULL; - self->is_owner = 0; + self->is_owner = false; } // diff --git a/library/foundation/definitions.cmake b/library/foundation/definitions.cmake index aefb8e864..a1854c73f 100644 --- a/library/foundation/definitions.cmake +++ b/library/foundation/definitions.cmake @@ -161,6 +161,7 @@ target_compile_definitions(foundation "VSCF_GROUP_SESSION=$" "VSCF_GROUP_SESSION_EPOCH=$" "VSCF_GROUP_SESSION_EPOCH_NODE=$" + "VSCF_MESSAGE_INFO_EDITOR=$" PRIVATE $<$:VSCF_BUILD_SHARED_LIBS> ) diff --git a/library/foundation/features.cmake b/library/foundation/features.cmake index 0816f0f4b..e82d2b126 100644 --- a/library/foundation/features.cmake +++ b/library/foundation/features.cmake @@ -154,6 +154,7 @@ option(VSCF_GROUP_SESSION_TICKET "Enable class 'group session ticket'." ON) option(VSCF_GROUP_SESSION "Enable class 'group session'." ON) option(VSCF_GROUP_SESSION_EPOCH "Enable class 'group session epoch'." ON) option(VSCF_GROUP_SESSION_EPOCH_NODE "Enable class 'group session epoch node'." ON) +option(VSCF_MESSAGE_INFO_EDITOR "Enable class 'message info editor'." ON) mark_as_advanced( VSCF_LIBRARY VSCF_MULTI_THREADING @@ -264,6 +265,7 @@ mark_as_advanced( VSCF_GROUP_SESSION VSCF_GROUP_SESSION_EPOCH VSCF_GROUP_SESSION_EPOCH_NODE + VSCF_MESSAGE_INFO_EDITOR ) if(VSCF_MULTI_THREADING AND NOT MBEDTLS_THREADING_C) @@ -2749,3 +2751,102 @@ if(VSCF_GROUP_SESSION AND NOT VSCF_PUBLIC_KEY) message("--") message(FATAL_ERROR) endif() + +if(VSCF_MESSAGE_INFO_EDITOR AND NOT VSCF_ENCRYPT) + message("-- error --") + message("--") + message("Feature VSCF_MESSAGE_INFO_EDITOR depends on the feature:") + message(" VSCF_ENCRYPT - which is disabled.") + message("--") + message(FATAL_ERROR) +endif() + +if(VSCF_MESSAGE_INFO_EDITOR AND NOT VSCF_DECRYPT) + message("-- error --") + message("--") + message("Feature VSCF_MESSAGE_INFO_EDITOR depends on the feature:") + message(" VSCF_DECRYPT - which is disabled.") + message("--") + message(FATAL_ERROR) +endif() + +if(VSCF_MESSAGE_INFO_EDITOR AND NOT VSCF_PUBLIC_KEY) + message("-- error --") + message("--") + message("Feature VSCF_MESSAGE_INFO_EDITOR depends on the feature:") + message(" VSCF_PUBLIC_KEY - which is disabled.") + message("--") + message(FATAL_ERROR) +endif() + +if(VSCF_MESSAGE_INFO_EDITOR AND NOT VSCF_PRIVATE_KEY) + message("-- error --") + message("--") + message("Feature VSCF_MESSAGE_INFO_EDITOR depends on the feature:") + message(" VSCF_PRIVATE_KEY - which is disabled.") + message("--") + message(FATAL_ERROR) +endif() + +if(VSCF_MESSAGE_INFO_EDITOR AND NOT VSCF_KEY_CIPHER) + message("-- error --") + message("--") + message("Feature VSCF_MESSAGE_INFO_EDITOR depends on the feature:") + message(" VSCF_KEY_CIPHER - which is disabled.") + message("--") + message(FATAL_ERROR) +endif() + +if(VSCF_MESSAGE_INFO_EDITOR AND NOT VSCF_MESSAGE_INFO_SERIALIZER) + message("-- error --") + message("--") + message("Feature VSCF_MESSAGE_INFO_EDITOR depends on the feature:") + message(" VSCF_MESSAGE_INFO_SERIALIZER - which is disabled.") + message("--") + message(FATAL_ERROR) +endif() + +if(VSCF_MESSAGE_INFO_EDITOR AND NOT VSCF_ALG_FACTORY) + message("-- error --") + message("--") + message("Feature VSCF_MESSAGE_INFO_EDITOR depends on the feature:") + message(" VSCF_ALG_FACTORY - which is disabled.") + message("--") + message(FATAL_ERROR) +endif() + +if(VSCF_MESSAGE_INFO_EDITOR AND NOT VSCF_KEY_ALG_FACTORY) + message("-- error --") + message("--") + message("Feature VSCF_MESSAGE_INFO_EDITOR depends on the feature:") + message(" VSCF_KEY_ALG_FACTORY - which is disabled.") + message("--") + message(FATAL_ERROR) +endif() + +if(VSCF_MESSAGE_INFO_EDITOR AND NOT VSCF_KEY_PROVIDER) + message("-- error --") + message("--") + message("Feature VSCF_MESSAGE_INFO_EDITOR depends on the feature:") + message(" VSCF_KEY_PROVIDER - which is disabled.") + message("--") + message(FATAL_ERROR) +endif() + +if(VSCF_MESSAGE_INFO_EDITOR AND NOT VSCF_CTR_DRBG) + message("-- error --") + message("--") + message("Feature VSCF_MESSAGE_INFO_EDITOR depends on the feature:") + message(" VSCF_CTR_DRBG - which is disabled.") + message("--") + message(FATAL_ERROR) +endif() + +if(VSCF_MESSAGE_INFO_EDITOR AND NOT VSCF_MESSAGE_INFO_DER_SERIALIZER) + message("-- error --") + message("--") + message("Feature VSCF_MESSAGE_INFO_EDITOR depends on the feature:") + message(" VSCF_MESSAGE_INFO_DER_SERIALIZER - which is disabled.") + message("--") + message(FATAL_ERROR) +endif() diff --git a/library/foundation/include/virgil/crypto/foundation/private/vscf_foundation_private.h b/library/foundation/include/virgil/crypto/foundation/private/vscf_foundation_private.h index 14ab4a258..57de223c7 100644 --- a/library/foundation/include/virgil/crypto/foundation/private/vscf_foundation_private.h +++ b/library/foundation/include/virgil/crypto/foundation/private/vscf_foundation_private.h @@ -118,6 +118,7 @@ #include "vscf_message_info_custom_params_defs.h" #include "vscf_message_info_defs.h" #include "vscf_message_info_der_serializer_defs.h" +#include "vscf_message_info_editor_defs.h" #include "vscf_message_info_serializer_api.h" #include "vscf_message_padding.h" #include "vscf_password_recipient_info_defs.h" diff --git a/library/foundation/include/virgil/crypto/foundation/private/vscf_message_info_editor_defs.h b/library/foundation/include/virgil/crypto/foundation/private/vscf_message_info_editor_defs.h new file mode 100644 index 000000000..362b4091a --- /dev/null +++ b/library/foundation/include/virgil/crypto/foundation/private/vscf_message_info_editor_defs.h @@ -0,0 +1,123 @@ +// @license +// -------------------------------------------------------------------------- +// Copyright (C) 2015-2019 Virgil Security, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// (1) Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// (2) Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// (3) Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Lead Maintainer: Virgil Security Inc. +// -------------------------------------------------------------------------- +// clang-format off + + +// @warning +// -------------------------------------------------------------------------- +// This file is partially generated. +// Generated blocks are enclosed between tags [@, @end]. +// User's code can be added between tags [@end, @]. +// -------------------------------------------------------------------------- + + +// @description +// -------------------------------------------------------------------------- +// Class 'message info editor' types definition. +// -------------------------------------------------------------------------- + +#ifndef VSCF_MESSAGE_INFO_EDITOR_DEFS_H_INCLUDED +#define VSCF_MESSAGE_INFO_EDITOR_DEFS_H_INCLUDED + +#include "vscf_library.h" +#include "vscf_atomic.h" +#include "vscf_message_info.h" +#include "vscf_impl.h" + +#if !VSCF_IMPORT_PROJECT_COMMON_FROM_FRAMEWORK +# include +#endif + +#if VSCF_IMPORT_PROJECT_COMMON_FROM_FRAMEWORK +# include +#endif + +// clang-format on +// @end + + +#ifdef __cplusplus +extern "C" { +#endif + + +// @generated +// -------------------------------------------------------------------------- +// clang-format off +// Generated section start. +// -------------------------------------------------------------------------- + +// +// Handle 'message info editor' context. +// +struct vscf_message_info_editor_t { + // + // Function do deallocate self context. + // + vscf_dealloc_fn self_dealloc_cb; + // + // Reference counter. + // + VSCF_ATOMIC size_t refcnt; + // + // Dependency to the interface 'random'. + // + vscf_impl_t *random; + + vscf_message_info_t *message_info; + + vscf_impl_t *message_info_serializer; + + vsc_buffer_t *encryption_key; +}; + + +// -------------------------------------------------------------------------- +// Generated section end. +// clang-format on +// -------------------------------------------------------------------------- +// @end + + +#ifdef __cplusplus +} +#endif + + +// @footer +#endif // VSCF_MESSAGE_INFO_EDITOR_DEFS_H_INCLUDED +// @end diff --git a/library/foundation/include/virgil/crypto/foundation/vscf_foundation_public.h b/library/foundation/include/virgil/crypto/foundation/vscf_foundation_public.h index e1ba0d414..1fa070e3e 100644 --- a/library/foundation/include/virgil/crypto/foundation/vscf_foundation_public.h +++ b/library/foundation/include/virgil/crypto/foundation/vscf_foundation_public.h @@ -126,6 +126,7 @@ #include "vscf_message_info.h" #include "vscf_message_info_custom_params.h" #include "vscf_message_info_der_serializer.h" +#include "vscf_message_info_editor.h" #include "vscf_message_info_serializer.h" #include "vscf_oid.h" #include "vscf_oid_id.h" diff --git a/library/foundation/include/virgil/crypto/foundation/vscf_key_recipient_info_list.h b/library/foundation/include/virgil/crypto/foundation/vscf_key_recipient_info_list.h index 8d3c6f75b..9368b117c 100644 --- a/library/foundation/include/virgil/crypto/foundation/vscf_key_recipient_info_list.h +++ b/library/foundation/include/virgil/crypto/foundation/vscf_key_recipient_info_list.h @@ -129,6 +129,12 @@ VSCF_PUBLIC void vscf_key_recipient_info_list_add(vscf_key_recipient_info_list_t *self, vscf_key_recipient_info_t **key_recipient_info_ref); +// +// Remove current node. +// +VSCF_PRIVATE void +vscf_key_recipient_info_list_remove_self(vscf_key_recipient_info_list_t *self); + // // Return true if given list has item. // @@ -153,6 +159,12 @@ vscf_key_recipient_info_list_has_next(const vscf_key_recipient_info_list_t *self VSCF_PUBLIC vscf_key_recipient_info_list_t * vscf_key_recipient_info_list_next(const vscf_key_recipient_info_list_t *self); +// +// Return next list node if exists, or NULL otherwise. +// +VSCF_PRIVATE vscf_key_recipient_info_list_t * +vscf_key_recipient_info_list_next_modifiable(vscf_key_recipient_info_list_t *self); + // // Return true if list has previous item. // diff --git a/library/foundation/include/virgil/crypto/foundation/vscf_message_info.h b/library/foundation/include/virgil/crypto/foundation/vscf_message_info.h index 8729b1441..778396ff7 100644 --- a/library/foundation/include/virgil/crypto/foundation/vscf_message_info.h +++ b/library/foundation/include/virgil/crypto/foundation/vscf_message_info.h @@ -157,6 +157,12 @@ vscf_message_info_data_encryption_alg_info(const vscf_message_info_t *self); VSCF_PUBLIC const vscf_key_recipient_info_list_t * vscf_message_info_key_recipient_info_list(const vscf_message_info_t *self); +// +// Return list with a "key recipient info" elements. +// +VSCF_PRIVATE vscf_key_recipient_info_list_t * +vscf_message_info_key_recipient_info_list_modifiable(vscf_message_info_t *self); + // // Return list with a "password recipient info" elements. // diff --git a/library/foundation/include/virgil/crypto/foundation/vscf_message_info_editor.h b/library/foundation/include/virgil/crypto/foundation/vscf_message_info_editor.h new file mode 100644 index 000000000..b4ed5c84b --- /dev/null +++ b/library/foundation/include/virgil/crypto/foundation/vscf_message_info_editor.h @@ -0,0 +1,220 @@ +// @license +// -------------------------------------------------------------------------- +// Copyright (C) 2015-2019 Virgil Security, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// (1) Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// (2) Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// (3) Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Lead Maintainer: Virgil Security Inc. +// -------------------------------------------------------------------------- +// clang-format off + + +// @warning +// -------------------------------------------------------------------------- +// This file is partially generated. +// Generated blocks are enclosed between tags [@, @end]. +// User's code can be added between tags [@end, @]. +// -------------------------------------------------------------------------- + + +// @description +// -------------------------------------------------------------------------- +// Add and/or remove recipients and it's paramteres within message info. +// +// Usage: +// 1. Unpack binary message info that was obtained from RecipientCipher. +// 2. Add and/or remove key recipients. +// 3. Pack MessagInfo to the binary data. +// -------------------------------------------------------------------------- + +#ifndef VSCF_MESSAGE_INFO_EDITOR_H_INCLUDED +#define VSCF_MESSAGE_INFO_EDITOR_H_INCLUDED + +#include "vscf_library.h" +#include "vscf_impl.h" +#include "vscf_status.h" + +#if !VSCF_IMPORT_PROJECT_COMMON_FROM_FRAMEWORK +# include +# include +#endif + +#if VSCF_IMPORT_PROJECT_COMMON_FROM_FRAMEWORK +# include +# include +#endif + +// clang-format on +// @end + + +#ifdef __cplusplus +extern "C" { +#endif + + +// @generated +// -------------------------------------------------------------------------- +// clang-format off +// Generated section start. +// -------------------------------------------------------------------------- + +// +// Handle 'message info editor' context. +// +typedef struct vscf_message_info_editor_t vscf_message_info_editor_t; + +// +// Return size of 'vscf_message_info_editor_t'. +// +VSCF_PUBLIC size_t +vscf_message_info_editor_ctx_size(void); + +// +// Perform initialization of pre-allocated context. +// +VSCF_PUBLIC void +vscf_message_info_editor_init(vscf_message_info_editor_t *self); + +// +// Release all inner resources including class dependencies. +// +VSCF_PUBLIC void +vscf_message_info_editor_cleanup(vscf_message_info_editor_t *self); + +// +// Allocate context and perform it's initialization. +// +VSCF_PUBLIC vscf_message_info_editor_t * +vscf_message_info_editor_new(void); + +// +// Release all inner resources and deallocate context if needed. +// It is safe to call this method even if the context was statically allocated. +// +VSCF_PUBLIC void +vscf_message_info_editor_delete(vscf_message_info_editor_t *self); + +// +// Delete given context and nullifies reference. +// This is a reverse action of the function 'vscf_message_info_editor_new ()'. +// +VSCF_PUBLIC void +vscf_message_info_editor_destroy(vscf_message_info_editor_t **self_ref); + +// +// Copy given class context by increasing reference counter. +// +VSCF_PUBLIC vscf_message_info_editor_t * +vscf_message_info_editor_shallow_copy(vscf_message_info_editor_t *self); + +// +// Setup dependency to the interface 'random' with shared ownership. +// +VSCF_PUBLIC void +vscf_message_info_editor_use_random(vscf_message_info_editor_t *self, vscf_impl_t *random); + +// +// Setup dependency to the interface 'random' and transfer ownership. +// Note, transfer ownership does not mean that object is uniquely owned by the target object. +// +VSCF_PUBLIC void +vscf_message_info_editor_take_random(vscf_message_info_editor_t *self, vscf_impl_t *random); + +// +// Release dependency to the interface 'random'. +// +VSCF_PUBLIC void +vscf_message_info_editor_release_random(vscf_message_info_editor_t *self); + +// +// Set depenencies to it's defaults. +// +VSCF_PUBLIC vscf_status_t +vscf_message_info_editor_setup_defaults(vscf_message_info_editor_t *self) VSCF_NODISCARD; + +// +// Unpack serialized message info. +// +VSCF_PUBLIC vscf_status_t +vscf_message_info_editor_unpack(vscf_message_info_editor_t *self, vsc_data_t message_info_data, + vsc_data_t owner_recipient_id, const vscf_impl_t *owner_private_key) VSCF_NODISCARD; + +// +// Add recipient defined with id and public key. +// +VSCF_PUBLIC vscf_status_t +vscf_message_info_editor_add_key_recipient(vscf_message_info_editor_t *self, vsc_data_t recipient_id, + const vscf_impl_t *public_key) VSCF_NODISCARD; + +// +// Remove recipient with a given id. +// Return false if recipient with given id was not found. +// +VSCF_PUBLIC bool +vscf_message_info_editor_remove_key_recipient(vscf_message_info_editor_t *self, vsc_data_t recipient_id); + +// +// Remove all existent recipients. +// +VSCF_PUBLIC void +vscf_message_info_editor_remove_all(vscf_message_info_editor_t *self); + +// +// Return length of serialized message info. +// Actual length can be obtained right after applying changes. +// +VSCF_PUBLIC size_t +vscf_message_info_editor_packed_len(const vscf_message_info_editor_t *self); + +// +// Return serialized message info. +// Precondition: this method can be called after "apply". +// +VSCF_PUBLIC void +vscf_message_info_editor_pack(vscf_message_info_editor_t *self, vsc_buffer_t *message_info); + + +// -------------------------------------------------------------------------- +// Generated section end. +// clang-format on +// -------------------------------------------------------------------------- +// @end + + +#ifdef __cplusplus +} +#endif + + +// @footer +#endif // VSCF_MESSAGE_INFO_EDITOR_H_INCLUDED +// @end diff --git a/library/foundation/include/virgil/crypto/foundation/vscf_platform.h.in b/library/foundation/include/virgil/crypto/foundation/vscf_platform.h.in index 6addc2333..4832f59b7 100644 --- a/library/foundation/include/virgil/crypto/foundation/vscf_platform.h.in +++ b/library/foundation/include/virgil/crypto/foundation/vscf_platform.h.in @@ -510,6 +510,10 @@ extern "C" { #cmakedefine01 VSCF_GROUP_SESSION_EPOCH_NODE #endif +#ifndef VSCF_MESSAGE_INFO_EDITOR +#cmakedefine01 VSCF_MESSAGE_INFO_EDITOR +#endif + // // Defines namespace include prefix for project 'common'. // diff --git a/library/foundation/include/virgil/crypto/foundation/vscf_recipient_cipher.h b/library/foundation/include/virgil/crypto/foundation/vscf_recipient_cipher.h index bce3e049a..d21fc246f 100644 --- a/library/foundation/include/virgil/crypto/foundation/vscf_recipient_cipher.h +++ b/library/foundation/include/virgil/crypto/foundation/vscf_recipient_cipher.h @@ -194,7 +194,7 @@ vscf_recipient_cipher_custom_params(vscf_recipient_cipher_t *self); // // Return buffer length required to hold message info returned by the -// "start encryption" method. +// "pack message info" method. // Precondition: all recipients and custom parameters should be set. // VSCF_PUBLIC size_t diff --git a/library/foundation/module.modulemap b/library/foundation/module.modulemap index dcafe2aba..3fea86988 100644 --- a/library/foundation/module.modulemap +++ b/library/foundation/module.modulemap @@ -92,6 +92,7 @@ framework module VSCFoundation { header "vscf_key_recipient_info_list.h" header "vscf_message_info.h" header "vscf_message_info_custom_params.h" + header "vscf_message_info_editor.h" header "vscf_oid.h" header "vscf_password_recipient_info.h" header "vscf_password_recipient_info_list.h" diff --git a/library/foundation/sources.cmake b/library/foundation/sources.cmake index 18f4a4097..e043997ac 100644 --- a/library/foundation/sources.cmake +++ b/library/foundation/sources.cmake @@ -523,6 +523,11 @@ set_property( PROPERTY MACOSX_PACKAGE_LOCATION "Headers" ) +set_property( + SOURCE "${CMAKE_CURRENT_LIST_DIR}/include/virgil/crypto/foundation/vscf_message_info_editor.h" + PROPERTY MACOSX_PACKAGE_LOCATION "Headers" +) + set_property( SOURCE "${CMAKE_CURRENT_LIST_DIR}/include/virgil/crypto/foundation/vscf_oid.h" PROPERTY MACOSX_PACKAGE_LOCATION "Headers" @@ -832,6 +837,8 @@ target_sources(foundation "$<$:${CMAKE_CURRENT_LIST_DIR}/include/virgil/crypto/foundation/vscf_message_info_custom_params.h>" "${CMAKE_CURRENT_LIST_DIR}/src/vscf_message_info_custom_params_internal.h" "$<$:${CMAKE_CURRENT_LIST_DIR}/include/virgil/crypto/foundation/private/vscf_message_info_custom_params_defs.h>" + "$<$:${CMAKE_CURRENT_LIST_DIR}/include/virgil/crypto/foundation/vscf_message_info_editor.h>" + "$<$:${CMAKE_CURRENT_LIST_DIR}/include/virgil/crypto/foundation/private/vscf_message_info_editor_defs.h>" "$<$:${CMAKE_CURRENT_LIST_DIR}/include/virgil/crypto/foundation/private/vscf_message_padding.h>" "$<$:${CMAKE_CURRENT_LIST_DIR}/src/vscf_message_padding_defs.h>" "$<$:${CMAKE_CURRENT_LIST_DIR}/include/virgil/crypto/foundation/vscf_oid.h>" @@ -1094,6 +1101,8 @@ target_sources(foundation "$<$:${CMAKE_CURRENT_LIST_DIR}/src/vscf_message_info_defs.c>" "$<$:${CMAKE_CURRENT_LIST_DIR}/src/vscf_message_info_custom_params.c>" "$<$:${CMAKE_CURRENT_LIST_DIR}/src/vscf_message_info_custom_params_defs.c>" + "$<$:${CMAKE_CURRENT_LIST_DIR}/src/vscf_message_info_editor.c>" + "$<$:${CMAKE_CURRENT_LIST_DIR}/src/vscf_message_info_editor_defs.c>" "$<$:${CMAKE_CURRENT_LIST_DIR}/src/vscf_message_padding.c>" "$<$:${CMAKE_CURRENT_LIST_DIR}/src/vscf_message_padding_defs.c>" "$<$:${CMAKE_CURRENT_LIST_DIR}/src/vscf_oid.c>" diff --git a/library/foundation/src/vscf_key_recipient_info_list.c b/library/foundation/src/vscf_key_recipient_info_list.c index 11091c811..5b97e76d9 100644 --- a/library/foundation/src/vscf_key_recipient_info_list.c +++ b/library/foundation/src/vscf_key_recipient_info_list.c @@ -270,6 +270,21 @@ vscf_key_recipient_info_list_add( } } +// +// Remove current node. +// +VSCF_PRIVATE void +vscf_key_recipient_info_list_remove_self(vscf_key_recipient_info_list_t *self) { + + VSCF_ASSERT_PTR(self); + + vscf_key_recipient_info_destroy(&self->item); + if (self->next) { + self->item = self->next->item; + self->next = self->next->next; + } +} + // // Return true if given list has item. // @@ -315,6 +330,17 @@ vscf_key_recipient_info_list_next(const vscf_key_recipient_info_list_t *self) { return self->next; } +// +// Return next list node if exists, or NULL otherwise. +// +VSCF_PRIVATE vscf_key_recipient_info_list_t * +vscf_key_recipient_info_list_next_modifiable(vscf_key_recipient_info_list_t *self) { + + VSCF_ASSERT_PTR(self); + + return self->next; +} + // // Return true if list has previous item. // diff --git a/library/foundation/src/vscf_message_info.c b/library/foundation/src/vscf_message_info.c index f59e1ab38..0f96e4dde 100644 --- a/library/foundation/src/vscf_message_info.c +++ b/library/foundation/src/vscf_message_info.c @@ -326,6 +326,18 @@ vscf_message_info_key_recipient_info_list(const vscf_message_info_t *self) { return self->key_recipients; } +// +// Return list with a "key recipient info" elements. +// +VSCF_PRIVATE vscf_key_recipient_info_list_t * +vscf_message_info_key_recipient_info_list_modifiable(vscf_message_info_t *self) { + + VSCF_ASSERT_PTR(self); + VSCF_ASSERT_PTR(self->key_recipients); + + return self->key_recipients; +} + // // Return list with a "password recipient info" elements. // diff --git a/library/foundation/src/vscf_message_info_editor.c b/library/foundation/src/vscf_message_info_editor.c new file mode 100644 index 000000000..7e81f403a --- /dev/null +++ b/library/foundation/src/vscf_message_info_editor.c @@ -0,0 +1,534 @@ +// @license +// -------------------------------------------------------------------------- +// Copyright (C) 2015-2019 Virgil Security, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// (1) Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// (2) Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// (3) Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Lead Maintainer: Virgil Security Inc. +// -------------------------------------------------------------------------- +// clang-format off + + +// @description +// -------------------------------------------------------------------------- +// Add and/or remove recipients and it's paramteres within message info. +// +// Usage: +// 1. Unpack binary message info that was obtained from RecipientCipher. +// 2. Add and/or remove key recipients. +// 3. Pack MessagInfo to the binary data. +// -------------------------------------------------------------------------- + + +// @warning +// -------------------------------------------------------------------------- +// This file is partially generated. +// Generated blocks are enclosed between tags [@, @end]. +// User's code can be added between tags [@end, @]. +// -------------------------------------------------------------------------- + +#include "vscf_message_info_editor.h" +#include "vscf_memory.h" +#include "vscf_assert.h" +#include "vscf_random.h" +#include "vscf_message_info_editor_defs.h" +#include "vscf_encrypt.h" +#include "vscf_decrypt.h" +#include "vscf_public_key.h" +#include "vscf_private_key.h" +#include "vscf_key_cipher.h" +#include "vscf_message_info_serializer.h" +#include "vscf_alg_factory.h" +#include "vscf_key_alg_factory.h" +#include "vscf_key_provider.h" +#include "vscf_ctr_drbg.h" +#include "vscf_message_info_der_serializer.h" + +// clang-format on +// @end + + +// @generated +// -------------------------------------------------------------------------- +// clang-format off +// Generated section start. +// -------------------------------------------------------------------------- + +// +// Perform context specific initialization. +// Note, this method is called automatically when method vscf_message_info_editor_init() is called. +// Note, that context is already zeroed. +// +static void +vscf_message_info_editor_init_ctx(vscf_message_info_editor_t *self); + +// +// Release all inner resources. +// Note, this method is called automatically once when class is completely cleaning up. +// Note, that context will be zeroed automatically next this method. +// +static void +vscf_message_info_editor_cleanup_ctx(vscf_message_info_editor_t *self); + +// +// Return size of 'vscf_message_info_editor_t'. +// +VSCF_PUBLIC size_t +vscf_message_info_editor_ctx_size(void) { + + return sizeof(vscf_message_info_editor_t); +} + +// +// Perform initialization of pre-allocated context. +// +VSCF_PUBLIC void +vscf_message_info_editor_init(vscf_message_info_editor_t *self) { + + VSCF_ASSERT_PTR(self); + + vscf_zeroize(self, sizeof(vscf_message_info_editor_t)); + + self->refcnt = 1; + + vscf_message_info_editor_init_ctx(self); +} + +// +// Release all inner resources including class dependencies. +// +VSCF_PUBLIC void +vscf_message_info_editor_cleanup(vscf_message_info_editor_t *self) { + + if (self == NULL) { + return; + } + + vscf_message_info_editor_cleanup_ctx(self); + + vscf_message_info_editor_release_random(self); + + vscf_zeroize(self, sizeof(vscf_message_info_editor_t)); +} + +// +// Allocate context and perform it's initialization. +// +VSCF_PUBLIC vscf_message_info_editor_t * +vscf_message_info_editor_new(void) { + + vscf_message_info_editor_t *self = (vscf_message_info_editor_t *) vscf_alloc(sizeof (vscf_message_info_editor_t)); + VSCF_ASSERT_ALLOC(self); + + vscf_message_info_editor_init(self); + + self->self_dealloc_cb = vscf_dealloc; + + return self; +} + +// +// Release all inner resources and deallocate context if needed. +// It is safe to call this method even if the context was statically allocated. +// +VSCF_PUBLIC void +vscf_message_info_editor_delete(vscf_message_info_editor_t *self) { + + if (self == NULL) { + return; + } + + size_t old_counter = self->refcnt; + VSCF_ASSERT(old_counter != 0); + size_t new_counter = old_counter - 1; + + #if defined(VSCF_ATOMIC_COMPARE_EXCHANGE_WEAK) + // CAS loop + while (!VSCF_ATOMIC_COMPARE_EXCHANGE_WEAK(&self->refcnt, &old_counter, new_counter)) { + old_counter = self->refcnt; + VSCF_ASSERT(old_counter != 0); + new_counter = old_counter - 1; + } + #else + self->refcnt = new_counter; + #endif + + if (new_counter > 0) { + return; + } + + vscf_dealloc_fn self_dealloc_cb = self->self_dealloc_cb; + + vscf_message_info_editor_cleanup(self); + + if (self_dealloc_cb != NULL) { + self_dealloc_cb(self); + } +} + +// +// Delete given context and nullifies reference. +// This is a reverse action of the function 'vscf_message_info_editor_new ()'. +// +VSCF_PUBLIC void +vscf_message_info_editor_destroy(vscf_message_info_editor_t **self_ref) { + + VSCF_ASSERT_PTR(self_ref); + + vscf_message_info_editor_t *self = *self_ref; + *self_ref = NULL; + + vscf_message_info_editor_delete(self); +} + +// +// Copy given class context by increasing reference counter. +// +VSCF_PUBLIC vscf_message_info_editor_t * +vscf_message_info_editor_shallow_copy(vscf_message_info_editor_t *self) { + + VSCF_ASSERT_PTR(self); + + #if defined(VSCF_ATOMIC_COMPARE_EXCHANGE_WEAK) + // CAS loop + size_t old_counter; + size_t new_counter; + do { + old_counter = self->refcnt; + new_counter = old_counter + 1; + } while (!VSCF_ATOMIC_COMPARE_EXCHANGE_WEAK(&self->refcnt, &old_counter, new_counter)); + #else + ++self->refcnt; + #endif + + return self; +} + +// +// Setup dependency to the interface 'random' with shared ownership. +// +VSCF_PUBLIC void +vscf_message_info_editor_use_random(vscf_message_info_editor_t *self, vscf_impl_t *random) { + + VSCF_ASSERT_PTR(self); + VSCF_ASSERT_PTR(random); + VSCF_ASSERT(self->random == NULL); + + VSCF_ASSERT(vscf_random_is_implemented(random)); + + self->random = vscf_impl_shallow_copy(random); +} + +// +// Setup dependency to the interface 'random' and transfer ownership. +// Note, transfer ownership does not mean that object is uniquely owned by the target object. +// +VSCF_PUBLIC void +vscf_message_info_editor_take_random(vscf_message_info_editor_t *self, vscf_impl_t *random) { + + VSCF_ASSERT_PTR(self); + VSCF_ASSERT_PTR(random); + VSCF_ASSERT(self->random == NULL); + + VSCF_ASSERT(vscf_random_is_implemented(random)); + + self->random = random; +} + +// +// Release dependency to the interface 'random'. +// +VSCF_PUBLIC void +vscf_message_info_editor_release_random(vscf_message_info_editor_t *self) { + + VSCF_ASSERT_PTR(self); + + vscf_impl_destroy(&self->random); +} + + +// -------------------------------------------------------------------------- +// Generated section end. +// clang-format on +// -------------------------------------------------------------------------- +// @end + + +// +// Perform context specific initialization. +// Note, this method is called automatically when method vscf_message_info_editor_init() is called. +// Note, that context is already zeroed. +// +static void +vscf_message_info_editor_init_ctx(vscf_message_info_editor_t *self) { + + VSCF_ASSERT_PTR(self); + + vscf_message_info_der_serializer_t *der_serializer = vscf_message_info_der_serializer_new(); + vscf_message_info_der_serializer_setup_defaults(der_serializer); + self->message_info_serializer = vscf_message_info_der_serializer_impl(der_serializer); + + self->encryption_key = vsc_buffer_new(); + vsc_buffer_make_secure(self->encryption_key); +} + +// +// Release all inner resources. +// Note, this method is called automatically once when class is completely cleaning up. +// Note, that context will be zeroed automatically next this method. +// +static void +vscf_message_info_editor_cleanup_ctx(vscf_message_info_editor_t *self) { + + VSCF_ASSERT_PTR(self); + + vscf_impl_destroy(&self->message_info_serializer); + vsc_buffer_destroy(&self->encryption_key); +} + +// +// Set depenencies to it's defaults. +// +VSCF_PUBLIC vscf_status_t +vscf_message_info_editor_setup_defaults(vscf_message_info_editor_t *self) { + + if (NULL == self->random) { + vscf_ctr_drbg_t *random = vscf_ctr_drbg_new(); + vscf_status_t status = vscf_ctr_drbg_setup_defaults(random); + if (status != vscf_status_SUCCESS) { + vscf_ctr_drbg_destroy(&random); + return status; + } + self->random = vscf_ctr_drbg_impl(random); + } + + return vscf_status_SUCCESS; +} + +// +// Unpack serialized message info. +// +VSCF_PUBLIC vscf_status_t +vscf_message_info_editor_unpack(vscf_message_info_editor_t *self, vsc_data_t message_info_data, + vsc_data_t owner_recipient_id, const vscf_impl_t *owner_private_key) { + + VSCF_ASSERT_PTR(self); + VSCF_ASSERT_PTR(self->random); + VSCF_ASSERT_PTR(self->message_info_serializer); + VSCF_ASSERT(vsc_data_is_valid(message_info_data)); + VSCF_ASSERT(vsc_data_is_valid(owner_recipient_id)); + VSCF_ASSERT_PTR(owner_private_key); + VSCF_ASSERT(vscf_private_key_is_implemented(owner_private_key)); + + vscf_error_t error; + vscf_error_reset(&error); + + // + // Cleanup + // + vscf_message_info_destroy(&self->message_info); + vsc_buffer_release(self->encryption_key); + + self->message_info = + vscf_message_info_serializer_deserialize(self->message_info_serializer, message_info_data, &error); + + if (vscf_error_has_error(&error)) { + return vscf_error_status(&error); + } + + // + // Decrypt encryption key. + // + for (const vscf_key_recipient_info_list_t *curr = vscf_message_info_key_recipient_info_list(self->message_info); + (curr != NULL) && vscf_key_recipient_info_list_has_item(curr); + curr = vscf_key_recipient_info_list_next(curr)) { + // + // Find recipient. + // + const vscf_key_recipient_info_t *recipient_info = vscf_key_recipient_info_list_item(curr); + if (vsc_data_equal(vscf_key_recipient_info_recipient_id(recipient_info), owner_recipient_id)) { + // + // Check algorithm that was used for encryption to be equal algorithm that will be used for + // decryption. + // + const vscf_impl_t *encryption_algorithm = vscf_key_recipient_info_key_encryption_algorithm(recipient_info); + + vscf_alg_id_t encryption_algorithm_alg_id = vscf_alg_info_alg_id(encryption_algorithm); + vscf_alg_id_t decryption_algorithm_alg_id = vscf_key_alg_id(owner_private_key); + + if (encryption_algorithm_alg_id != decryption_algorithm_alg_id) { + return vscf_status_ERROR_BAD_MESSAGE_INFO; + } + + vscf_impl_t *key_alg = vscf_key_alg_factory_create_from_key(owner_private_key, self->random, &error); + if (vscf_error_has_error(&error)) { + return vscf_error_status(&error); + } + + // + // Decrypt encryption key. + // + vsc_data_t encrypted_key = vscf_key_recipient_info_encrypted_key(recipient_info); + + const size_t encryption_key_len = + vscf_key_cipher_decrypted_len(key_alg, owner_private_key, encrypted_key.len); + vsc_buffer_alloc(self->encryption_key, encryption_key_len); + + vscf_status_t status = + vscf_key_cipher_decrypt(key_alg, owner_private_key, encrypted_key, self->encryption_key); + + vscf_impl_destroy(&key_alg); + + if (status != vscf_status_SUCCESS) { + return vscf_status_ERROR_KEY_RECIPIENT_PRIVATE_KEY_IS_WRONG; + } + + return vscf_status_SUCCESS; + } + } + + return vscf_status_ERROR_KEY_RECIPIENT_IS_NOT_FOUND; +} + +// +// Add recipient defined with id and public key. +// +VSCF_PUBLIC vscf_status_t +vscf_message_info_editor_add_key_recipient( + vscf_message_info_editor_t *self, vsc_data_t recipient_id, const vscf_impl_t *public_key) { + + VSCF_ASSERT_PTR(self); + VSCF_ASSERT_PTR(self->random); + VSCF_ASSERT(vsc_buffer_is_valid(self->encryption_key)); + VSCF_ASSERT(vsc_data_is_valid(recipient_id)); + VSCF_ASSERT_PTR(public_key); + VSCF_ASSERT(vscf_public_key_is_implemented(public_key)); + + vscf_error_t error; + vscf_error_reset(&error); + + vscf_impl_t *key_alg = vscf_key_alg_factory_create_from_key(public_key, self->random, &error); + if (vscf_error_has_error(&error)) { + return vscf_error_status(&error); + } + VSCF_ASSERT(vscf_key_cipher_is_implemented(key_alg)); + + const size_t encrypted_key_len = + vscf_key_cipher_encrypted_len(key_alg, public_key, vsc_buffer_len(self->encryption_key)); + vsc_buffer_t *encrypted_key = vsc_buffer_new_with_capacity(encrypted_key_len); + error.status = vscf_key_cipher_encrypt(key_alg, public_key, vsc_buffer_data(self->encryption_key), encrypted_key); + vscf_impl_destroy(&key_alg); + + if (vscf_error_has_error(&error)) { + vsc_buffer_destroy(&encrypted_key); + return vscf_error_status(&error); + } + + vscf_key_recipient_info_t *recipient_info = + vscf_key_recipient_info_new_with_buffer(recipient_id, vscf_key_alg_info(public_key), &encrypted_key); + + vscf_message_info_add_key_recipient(self->message_info, &recipient_info); + + return vscf_status_SUCCESS; +} + +// +// Remove recipient with a given id. +// Return false if recipient with given id was not found. +// +VSCF_PUBLIC bool +vscf_message_info_editor_remove_key_recipient(vscf_message_info_editor_t *self, vsc_data_t recipient_id) { + + VSCF_ASSERT_PTR(self); + VSCF_ASSERT_PTR(self->message_info); + VSCF_ASSERT(vsc_data_is_valid(recipient_id)); + + for (vscf_key_recipient_info_list_t *curr = + vscf_message_info_key_recipient_info_list_modifiable(self->message_info); + (curr != NULL) && vscf_key_recipient_info_list_has_item(curr); + curr = vscf_key_recipient_info_list_next_modifiable(curr)) { + // + // Find recipient. + // + const vscf_key_recipient_info_t *recipient_info = vscf_key_recipient_info_list_item(curr); + if (vsc_data_equal(vscf_key_recipient_info_recipient_id(recipient_info), recipient_id)) { + vscf_key_recipient_info_list_remove_self(curr); + return true; + } + } + + return false; +} + +// +// Remove all existent recipients. +// +VSCF_PUBLIC void +vscf_message_info_editor_remove_all(vscf_message_info_editor_t *self) { + + VSCF_ASSERT_PTR(self); + VSCF_ASSERT_PTR(self->message_info); + + vscf_key_recipient_info_list_t *key_recipients = + vscf_message_info_key_recipient_info_list_modifiable(self->message_info); + vscf_key_recipient_info_list_clear(key_recipients); +} + +// +// Return length of serialized message info. +// Actual length can be obtained right after applying changes. +// +VSCF_PUBLIC size_t +vscf_message_info_editor_packed_len(const vscf_message_info_editor_t *self) { + + VSCF_ASSERT(self); + VSCF_ASSERT(self->message_info); + VSCF_ASSERT(self->message_info_serializer); + + return vscf_message_info_serializer_serialized_len(self->message_info_serializer, self->message_info); +} + +// +// Return serialized message info. +// Precondition: this method can be called after "apply". +// +VSCF_PUBLIC void +vscf_message_info_editor_pack(vscf_message_info_editor_t *self, vsc_buffer_t *message_info) { + + VSCF_ASSERT_PTR(self); + VSCF_ASSERT_PTR(self->message_info); + VSCF_ASSERT_PTR(self->message_info_serializer); + VSCF_ASSERT_PTR(message_info); + VSCF_ASSERT(vsc_buffer_is_valid(message_info)); + VSCF_ASSERT(vsc_buffer_unused_len(message_info) >= vscf_message_info_editor_packed_len(self)); + + vscf_message_info_serializer_serialize(self->message_info_serializer, self->message_info, message_info); +} diff --git a/library/foundation/src/vscf_message_info_editor_defs.c b/library/foundation/src/vscf_message_info_editor_defs.c new file mode 100644 index 000000000..21a1a5178 --- /dev/null +++ b/library/foundation/src/vscf_message_info_editor_defs.c @@ -0,0 +1,70 @@ +// @license +// -------------------------------------------------------------------------- +// Copyright (C) 2015-2019 Virgil Security, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// (1) Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// (2) Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// (3) Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Lead Maintainer: Virgil Security Inc. +// -------------------------------------------------------------------------- +// clang-format off + + +// @description +// -------------------------------------------------------------------------- +// Class 'message info editor' types definition. +// -------------------------------------------------------------------------- + + +// @warning +// -------------------------------------------------------------------------- +// This file is partially generated. +// Generated blocks are enclosed between tags [@, @end]. +// User's code can be added between tags [@end, @]. +// -------------------------------------------------------------------------- + +#include "vscf_message_info_editor_defs.h" + +// clang-format on +// @end + + +// @generated +// -------------------------------------------------------------------------- +// clang-format off +// Generated section start. +// -------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------- +// Generated section end. +// clang-format on +// -------------------------------------------------------------------------- +// @end diff --git a/library/foundation/src/vscf_recipient_cipher.c b/library/foundation/src/vscf_recipient_cipher.c index 208faad88..b3d4fcc72 100644 --- a/library/foundation/src/vscf_recipient_cipher.c +++ b/library/foundation/src/vscf_recipient_cipher.c @@ -441,7 +441,7 @@ vscf_recipient_cipher_custom_params(vscf_recipient_cipher_t *self) { // // Return buffer length required to hold message info returned by the -// "start encryption" method. +// "pack message info" method. // Precondition: all recipients and custom parameters should be set. // VSCF_PUBLIC size_t diff --git a/tests/foundation/CMakeLists.txt b/tests/foundation/CMakeLists.txt index e55a6e248..da7c7475b 100644 --- a/tests/foundation/CMakeLists.txt +++ b/tests/foundation/CMakeLists.txt @@ -100,6 +100,7 @@ _add_test (test_brainkey_server) _add_test (test_simple_swu) _add_test (test_group_session) _add_test (test_group_message) +_add_test (test_message_info_editor) # --------------------------------------------------------------------------- # Multi-threading tests diff --git a/tests/foundation/data/CMakeLists.txt b/tests/foundation/data/CMakeLists.txt index b89207a2d..996f14891 100644 --- a/tests/foundation/data/CMakeLists.txt +++ b/tests/foundation/data/CMakeLists.txt @@ -72,6 +72,7 @@ target_sources(test_data_foundation "${CMAKE_CURRENT_LIST_DIR}/include/test_data_brainkey_client.h" "${CMAKE_CURRENT_LIST_DIR}/include/test_data_simple_swu.h" "${CMAKE_CURRENT_LIST_DIR}/include/test_data_group_session.h" + "${CMAKE_CURRENT_LIST_DIR}/include/test_data_message_info.h" PRIVATE "${CMAKE_CURRENT_LIST_DIR}/src/test_data_aes256_gcm.c" @@ -107,6 +108,7 @@ target_sources(test_data_foundation "${CMAKE_CURRENT_LIST_DIR}/src/test_data_brainkey_client.c" "${CMAKE_CURRENT_LIST_DIR}/src/test_data_simple_swu.c" "${CMAKE_CURRENT_LIST_DIR}/src/test_data_group_session.c" + "${CMAKE_CURRENT_LIST_DIR}/src/test_data_message_info.c" ) target_include_directories(test_data_foundation diff --git a/tests/foundation/data/include/test_data_message_info.h b/tests/foundation/data/include/test_data_message_info.h new file mode 100644 index 000000000..7d76db671 --- /dev/null +++ b/tests/foundation/data/include/test_data_message_info.h @@ -0,0 +1,47 @@ +// Copyright (C) 2015-2018 Virgil Security Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// (1) Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// (2) Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// (3) Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Lead Maintainer: Virgil Security Inc. + +#include "vsc_data.h" + +extern const vsc_data_t test_data_message_info_RSA2048_RECIPIENT_ID; +extern const vsc_data_t test_data_message_info_RSA2048_PUBLIC_KEY; +extern const vsc_data_t test_data_message_info_RSA2048_PRIVATE_KEY; +extern const vsc_data_t test_data_message_info_MESSAGE_INFO_WITH_ONE_RSA2048_RECIPIENT; + +extern const vsc_data_t test_data_message_info_ED25519_RECIPIENT_ID; +extern const vsc_data_t test_data_message_info_ED25519_PUBLIC_KEY; +extern const vsc_data_t test_data_message_info_ED25519_PRIVATE_KEY; +extern const vsc_data_t test_data_message_info_MESSAGE_INFO_WITH_ONE_ED25519_RECIPIENT; + +extern const vsc_data_t test_data_message_info_MESSAGE_INFO_WITH_ONE_ED25519_RECIPIENT_AND_ONE_RSA2048_RECIPIENT; diff --git a/tests/foundation/data/src/test_data_message_info.c b/tests/foundation/data/src/test_data_message_info.c new file mode 100644 index 000000000..ee57d5aa6 --- /dev/null +++ b/tests/foundation/data/src/test_data_message_info.c @@ -0,0 +1,491 @@ +// Copyright (C) 2015-2018 Virgil Security Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// (1) Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// (2) Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// (3) Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Lead Maintainer: Virgil Security Inc. + +#include "test_data_message_info.h" + +static const byte RSA2048_RECIPIENT_ID[] = { + 0xE9, 0x5F, 0x12, 0x2C, 0x87, 0x2B, 0x54, 0x85, + 0x85, 0x3F, 0xDF, 0x9C, 0xF3, 0x73, 0x9A, 0x9F, + 0x4E, 0xBF, 0xC3, 0x6C, 0x95, 0xF5, 0x7B, 0x69, + 0x1F, 0x4A, 0xE8, 0x87, 0x18, 0xD4, 0x21, 0xD8, +}; + +const vsc_data_t test_data_message_info_RSA2048_RECIPIENT_ID = { + RSA2048_RECIPIENT_ID, sizeof(RSA2048_RECIPIENT_ID) +}; + +static const byte RSA2048_PUBLIC_KEY[] = { + 0x30, 0x82, 0x01, 0x21, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0e, 0x00, + 0x30, 0x82, 0x01, 0x09, 0x02, 0x82, 0x01, 0x00, + 0x53, 0x7c, 0xc7, 0xe8, 0xfb, 0x4b, 0x09, 0x75, + 0x73, 0x9f, 0x3f, 0xf6, 0x13, 0xd0, 0x1a, 0x98, + 0xd5, 0x03, 0x9e, 0xb8, 0x59, 0xc0, 0xfd, 0x8b, + 0x01, 0xdf, 0x72, 0xa6, 0x36, 0x73, 0xef, 0xad, + 0x12, 0x1c, 0x33, 0x74, 0x6f, 0x2a, 0x1c, 0x1b, + 0xe4, 0x39, 0x99, 0xcf, 0xc5, 0x45, 0xfa, 0xb8, + 0x97, 0x56, 0x91, 0x31, 0xae, 0x7e, 0xb7, 0x60, + 0x13, 0xe8, 0x7a, 0xc3, 0x27, 0x07, 0xa9, 0xc9, + 0x10, 0xf1, 0x3a, 0xa7, 0x98, 0xcf, 0xa0, 0x5e, + 0x78, 0x71, 0x1b, 0x71, 0x6b, 0xb5, 0xc8, 0xf3, + 0xa7, 0x0b, 0xad, 0xd3, 0x7e, 0x93, 0x75, 0xac, + 0xf7, 0x52, 0xc1, 0xd0, 0x96, 0xa9, 0xef, 0xba, + 0xed, 0x84, 0x84, 0x72, 0x1e, 0x9e, 0xbb, 0x08, + 0x65, 0xfd, 0x0c, 0x55, 0x47, 0x09, 0x46, 0x17, + 0xd7, 0x13, 0xf8, 0x6f, 0x92, 0xa3, 0x2f, 0x43, + 0xd6, 0xfd, 0x3b, 0x52, 0xd5, 0x85, 0x5c, 0x73, + 0x84, 0x50, 0x4a, 0xad, 0x7f, 0xdf, 0x95, 0xce, + 0xff, 0xef, 0x80, 0x6a, 0xed, 0x6b, 0x75, 0xeb, + 0xd6, 0x50, 0xb7, 0x33, 0xee, 0xee, 0xea, 0x53, + 0x47, 0x9e, 0xf3, 0x8f, 0x59, 0xc5, 0xf6, 0x82, + 0x90, 0x72, 0x4a, 0x62, 0xed, 0xd0, 0x13, 0xdb, + 0xb6, 0xee, 0xa5, 0x66, 0xfd, 0x5c, 0xb4, 0x4e, + 0x7a, 0xcd, 0xc0, 0x27, 0xe4, 0x8f, 0x7d, 0xb6, + 0x20, 0xde, 0x7e, 0xca, 0xb1, 0x87, 0xc3, 0x14, + 0x98, 0x7b, 0xad, 0xe4, 0xcb, 0xe1, 0xd1, 0x9d, + 0xd4, 0x3b, 0x0c, 0x86, 0xef, 0xf9, 0x00, 0xeb, + 0x4e, 0xe1, 0xf7, 0x93, 0xe8, 0xd0, 0x33, 0xd9, + 0x45, 0x9b, 0x14, 0x6a, 0xaf, 0xf9, 0x97, 0x1d, + 0xc1, 0xc7, 0x27, 0x40, 0x8e, 0x97, 0x22, 0xa9, + 0x1d, 0x27, 0xae, 0x3b, 0xb3, 0x15, 0x1e, 0x97, + 0xae, 0xc7, 0xf3, 0x60, 0x56, 0x22, 0xa0, 0xe3, + 0x8b, 0x8b, 0xb4, 0xea, 0x46, 0xe6, 0x10, 0xeb, + 0x02, 0x03, 0x01, 0x00, 0x01 +}; + +const vsc_data_t test_data_message_info_RSA2048_PUBLIC_KEY = { + RSA2048_PUBLIC_KEY, sizeof(RSA2048_PUBLIC_KEY) +}; + +static const byte RSA2048_PRIVATE_KEY[] = { + 0x30, 0x82, 0x04, 0xbc, 0x02, 0x01, 0x00, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, + 0x04, 0xa6, 0x30, 0x82, 0x04, 0xa2, 0x02, 0x01, + 0x00, 0x02, 0x82, 0x01, 0x00, 0x53, 0x7c, 0xc7, + 0xe8, 0xfb, 0x4b, 0x09, 0x75, 0x73, 0x9f, 0x3f, + 0xf6, 0x13, 0xd0, 0x1a, 0x98, 0xd5, 0x03, 0x9e, + 0xb8, 0x59, 0xc0, 0xfd, 0x8b, 0x01, 0xdf, 0x72, + 0xa6, 0x36, 0x73, 0xef, 0xad, 0x12, 0x1c, 0x33, + 0x74, 0x6f, 0x2a, 0x1c, 0x1b, 0xe4, 0x39, 0x99, + 0xcf, 0xc5, 0x45, 0xfa, 0xb8, 0x97, 0x56, 0x91, + 0x31, 0xae, 0x7e, 0xb7, 0x60, 0x13, 0xe8, 0x7a, + 0xc3, 0x27, 0x07, 0xa9, 0xc9, 0x10, 0xf1, 0x3a, + 0xa7, 0x98, 0xcf, 0xa0, 0x5e, 0x78, 0x71, 0x1b, + 0x71, 0x6b, 0xb5, 0xc8, 0xf3, 0xa7, 0x0b, 0xad, + 0xd3, 0x7e, 0x93, 0x75, 0xac, 0xf7, 0x52, 0xc1, + 0xd0, 0x96, 0xa9, 0xef, 0xba, 0xed, 0x84, 0x84, + 0x72, 0x1e, 0x9e, 0xbb, 0x08, 0x65, 0xfd, 0x0c, + 0x55, 0x47, 0x09, 0x46, 0x17, 0xd7, 0x13, 0xf8, + 0x6f, 0x92, 0xa3, 0x2f, 0x43, 0xd6, 0xfd, 0x3b, + 0x52, 0xd5, 0x85, 0x5c, 0x73, 0x84, 0x50, 0x4a, + 0xad, 0x7f, 0xdf, 0x95, 0xce, 0xff, 0xef, 0x80, + 0x6a, 0xed, 0x6b, 0x75, 0xeb, 0xd6, 0x50, 0xb7, + 0x33, 0xee, 0xee, 0xea, 0x53, 0x47, 0x9e, 0xf3, + 0x8f, 0x59, 0xc5, 0xf6, 0x82, 0x90, 0x72, 0x4a, + 0x62, 0xed, 0xd0, 0x13, 0xdb, 0xb6, 0xee, 0xa5, + 0x66, 0xfd, 0x5c, 0xb4, 0x4e, 0x7a, 0xcd, 0xc0, + 0x27, 0xe4, 0x8f, 0x7d, 0xb6, 0x20, 0xde, 0x7e, + 0xca, 0xb1, 0x87, 0xc3, 0x14, 0x98, 0x7b, 0xad, + 0xe4, 0xcb, 0xe1, 0xd1, 0x9d, 0xd4, 0x3b, 0x0c, + 0x86, 0xef, 0xf9, 0x00, 0xeb, 0x4e, 0xe1, 0xf7, + 0x93, 0xe8, 0xd0, 0x33, 0xd9, 0x45, 0x9b, 0x14, + 0x6a, 0xaf, 0xf9, 0x97, 0x1d, 0xc1, 0xc7, 0x27, + 0x40, 0x8e, 0x97, 0x22, 0xa9, 0x1d, 0x27, 0xae, + 0x3b, 0xb3, 0x15, 0x1e, 0x97, 0xae, 0xc7, 0xf3, + 0x60, 0x56, 0x22, 0xa0, 0xe3, 0x8b, 0x8b, 0xb4, + 0xea, 0x46, 0xe6, 0x10, 0xeb, 0x02, 0x03, 0x01, + 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x48, 0xa0, + 0xa0, 0x77, 0xf9, 0x43, 0xc9, 0xb2, 0xb7, 0x26, + 0xae, 0x49, 0xaf, 0xea, 0xb5, 0x78, 0x86, 0xb6, + 0x63, 0x79, 0x13, 0xfb, 0x63, 0x95, 0x6d, 0xc7, + 0xa8, 0xc1, 0x17, 0x55, 0xbc, 0x06, 0xdf, 0x5e, + 0x51, 0x14, 0xd5, 0x2f, 0xd8, 0xcc, 0x1a, 0xba, + 0x51, 0x28, 0x02, 0x01, 0x62, 0x9e, 0xfa, 0x68, + 0x80, 0x5e, 0xab, 0xe1, 0xe8, 0x3c, 0x58, 0x95, + 0x41, 0x56, 0x4b, 0xb9, 0xca, 0xe5, 0xf3, 0x2b, + 0x27, 0x4f, 0x6d, 0x0c, 0x12, 0x02, 0x9c, 0xdc, + 0x28, 0x77, 0x7e, 0xaf, 0xe1, 0x64, 0xb4, 0xc8, + 0xe0, 0x2a, 0xc0, 0x4e, 0x1f, 0x6c, 0x9c, 0xab, + 0x0d, 0x98, 0x1b, 0xb9, 0x31, 0xa7, 0x77, 0xc0, + 0x74, 0x47, 0xa2, 0x83, 0x8b, 0x49, 0x3f, 0x0f, + 0xe7, 0x8e, 0xb8, 0x01, 0x45, 0x4c, 0xaf, 0xf9, + 0xdb, 0x81, 0x94, 0x1b, 0x09, 0x9f, 0x06, 0x83, + 0xbc, 0xfb, 0xce, 0x6b, 0xf9, 0x84, 0x34, 0x7f, + 0xc0, 0xf3, 0xb6, 0x93, 0xa4, 0xa3, 0x55, 0x68, + 0x7f, 0xd4, 0x64, 0xaa, 0x72, 0x89, 0xd3, 0x4c, + 0x5b, 0x86, 0x68, 0x95, 0xdd, 0x41, 0xaa, 0xbb, + 0x54, 0xd0, 0xb3, 0x40, 0x74, 0x75, 0x67, 0x46, + 0x9c, 0xea, 0xa3, 0x6f, 0x39, 0x20, 0xdf, 0x1c, + 0x39, 0x3c, 0x9b, 0x8f, 0xca, 0x82, 0x4e, 0x2b, + 0xe7, 0x41, 0xa0, 0x94, 0xd7, 0x92, 0x25, 0x9d, + 0x5c, 0xb7, 0x1a, 0x98, 0x1e, 0xed, 0x71, 0x27, + 0x18, 0x1e, 0x61, 0xb9, 0x14, 0x7f, 0x25, 0x73, + 0x98, 0x2d, 0x7a, 0x31, 0xc7, 0x05, 0xb0, 0x89, + 0xc3, 0x88, 0x1d, 0xd2, 0x85, 0xab, 0x0e, 0x8d, + 0xc7, 0x75, 0x24, 0x9c, 0xe3, 0xaf, 0xcc, 0xc1, + 0x9c, 0xe1, 0xfb, 0xa4, 0x67, 0x6b, 0x84, 0xdd, + 0x79, 0x05, 0x7a, 0xa2, 0xb0, 0xe8, 0x72, 0xa5, + 0xee, 0xc9, 0x83, 0x57, 0xe3, 0x1b, 0x0b, 0x58, + 0xdc, 0xcb, 0xf6, 0x01, 0xd2, 0x21, 0x02, 0x81, + 0x81, 0x00, 0xa3, 0x79, 0xb8, 0xfd, 0xb3, 0x1d, + 0x79, 0x53, 0x25, 0x61, 0x3b, 0x14, 0x72, 0x2c, + 0x91, 0xc2, 0xdf, 0x5b, 0x4b, 0x1d, 0x79, 0x68, + 0xfa, 0x18, 0x03, 0xdc, 0x57, 0x44, 0x93, 0xf0, + 0x72, 0x7a, 0xfe, 0xa8, 0x2a, 0x1a, 0x83, 0x76, + 0x35, 0x32, 0xb4, 0xa4, 0x48, 0x49, 0x71, 0xd7, + 0x89, 0x8a, 0x17, 0x9b, 0xaf, 0xf9, 0x21, 0x99, + 0x6c, 0x74, 0xdd, 0x92, 0x0b, 0x5a, 0x01, 0x19, + 0x57, 0x45, 0x1c, 0x3c, 0x5e, 0xe0, 0x17, 0x8a, + 0x0e, 0x5b, 0x56, 0x73, 0xc5, 0x6d, 0x56, 0x0e, + 0xc5, 0x4f, 0xcb, 0x1e, 0x18, 0xd6, 0xa8, 0xbd, + 0x0b, 0x12, 0x15, 0xf0, 0x20, 0xcb, 0x1d, 0xef, + 0x12, 0xdb, 0x03, 0x25, 0xf9, 0x33, 0x7f, 0x40, + 0x39, 0xa7, 0x9f, 0xca, 0xae, 0x33, 0x5e, 0x06, + 0x94, 0x23, 0x67, 0x5a, 0x00, 0x0f, 0x1f, 0x73, + 0x37, 0xfc, 0x86, 0x1f, 0x0a, 0x24, 0x63, 0x55, + 0xa0, 0xdd, 0x02, 0x81, 0x81, 0x00, 0x82, 0xbd, + 0x6f, 0x58, 0xf1, 0x21, 0xe6, 0xc8, 0xdc, 0xa3, + 0xd6, 0x2c, 0x20, 0x79, 0xae, 0x7d, 0xad, 0xd8, + 0xd9, 0xf1, 0x8c, 0x67, 0x8a, 0x36, 0xe1, 0xd9, + 0x7e, 0xba, 0x58, 0xd7, 0x39, 0x2d, 0x5c, 0x64, + 0x1b, 0x23, 0xef, 0x4f, 0x17, 0x2e, 0xf6, 0x45, + 0x02, 0x7f, 0x6d, 0xf8, 0xea, 0xd0, 0xeb, 0xda, + 0x15, 0x4b, 0x72, 0x3b, 0x98, 0x21, 0x2d, 0xd1, + 0xbf, 0x7c, 0x4b, 0x90, 0xaa, 0x8a, 0xad, 0x06, + 0xfe, 0xab, 0xee, 0xaa, 0x3f, 0x8c, 0xbb, 0xe0, + 0x2e, 0xb8, 0xd0, 0xe5, 0xb8, 0x19, 0x35, 0x6b, + 0xce, 0x6c, 0x0f, 0x55, 0x9e, 0x25, 0x9f, 0xf4, + 0xff, 0x11, 0xc4, 0x5b, 0xea, 0x46, 0xdf, 0xab, + 0xf7, 0x98, 0x3d, 0x05, 0x9a, 0xb6, 0xae, 0x28, + 0xc2, 0xbc, 0x64, 0xe5, 0xd3, 0x33, 0x5e, 0x96, + 0xb2, 0xa4, 0x46, 0x37, 0x1c, 0xf3, 0x19, 0x17, + 0xa3, 0x70, 0xf0, 0x2a, 0x38, 0x67, 0x02, 0x81, + 0x80, 0x70, 0x21, 0x79, 0x13, 0x83, 0xfd, 0xae, + 0x8f, 0xaa, 0xaf, 0x23, 0xd0, 0x25, 0x74, 0x8e, + 0xd2, 0xc5, 0x54, 0x20, 0x94, 0xea, 0x07, 0x68, + 0xac, 0x7a, 0x51, 0x74, 0x06, 0x95, 0x17, 0x33, + 0xdf, 0x4b, 0xb7, 0xdb, 0x91, 0x6e, 0x24, 0xf1, + 0xde, 0x82, 0xeb, 0xc0, 0xad, 0xa8, 0x09, 0xb8, + 0xcc, 0xe0, 0xde, 0xa8, 0x78, 0xd1, 0x64, 0x24, + 0x71, 0x90, 0xdd, 0xb1, 0x2d, 0x9e, 0x5d, 0x5c, + 0x70, 0x0a, 0x2b, 0x1a, 0xc4, 0xc9, 0x40, 0xa8, + 0x12, 0x5c, 0x9d, 0x72, 0x89, 0x49, 0xa3, 0x3e, + 0x12, 0x3a, 0x77, 0xbd, 0x7f, 0xd8, 0x24, 0x3b, + 0x68, 0xbf, 0x65, 0x83, 0x88, 0xef, 0x52, 0x62, + 0x73, 0x99, 0x98, 0x3d, 0x73, 0xe6, 0x50, 0x0e, + 0x7b, 0xfc, 0xee, 0x10, 0x49, 0x29, 0xb0, 0x87, + 0x82, 0x35, 0x4d, 0x15, 0x87, 0x4a, 0x02, 0x45, + 0x1f, 0xd0, 0x7b, 0x90, 0x00, 0x5f, 0xa6, 0x87, + 0x7d, 0x02, 0x81, 0x80, 0x4a, 0x9f, 0x93, 0xd1, + 0xa1, 0x78, 0xe7, 0x40, 0x98, 0xe7, 0x8f, 0x14, + 0x8a, 0xc8, 0xc9, 0x77, 0x04, 0xe6, 0xb4, 0xa7, + 0x71, 0xab, 0x9b, 0xb1, 0x6d, 0xc1, 0xf5, 0xda, + 0xa9, 0x60, 0xd7, 0x4a, 0xf3, 0xe4, 0x53, 0xb5, + 0x74, 0x1f, 0xa1, 0xac, 0xf5, 0x76, 0x38, 0x51, + 0xc1, 0xd4, 0x85, 0x3b, 0x10, 0x93, 0xde, 0xf9, + 0xbc, 0x4f, 0x15, 0xab, 0x42, 0x7a, 0xe9, 0x20, + 0x2a, 0x05, 0x7d, 0xc2, 0x3f, 0xb6, 0xb1, 0x60, + 0x33, 0x8e, 0xcb, 0x4d, 0x29, 0xe3, 0x70, 0xe7, + 0x9e, 0x9c, 0xb0, 0x32, 0xfb, 0x51, 0xf8, 0x75, + 0xa7, 0x5f, 0x08, 0x30, 0x93, 0x97, 0x84, 0x8b, + 0x80, 0x97, 0xb2, 0x26, 0x17, 0xff, 0x11, 0x08, + 0xbd, 0x33, 0xd8, 0xb6, 0x12, 0xbc, 0x43, 0x42, + 0xc3, 0x18, 0x87, 0x2f, 0x57, 0xfb, 0x0e, 0x26, + 0x43, 0xc9, 0xab, 0x65, 0x7a, 0x5a, 0x0a, 0xb9, + 0x28, 0xec, 0x00, 0x5b, 0x02, 0x81, 0x81, 0x00, + 0x94, 0x69, 0x45, 0xf8, 0x1b, 0xd8, 0x13, 0xfd, + 0x29, 0xf9, 0x9d, 0xa0, 0xee, 0x71, 0xd9, 0x94, + 0xcc, 0x30, 0x25, 0xfc, 0x78, 0x1a, 0xc9, 0xa3, + 0x1d, 0x73, 0x49, 0x51, 0xa5, 0xd7, 0x65, 0xc9, + 0xa3, 0xf7, 0x6d, 0x35, 0xa5, 0x18, 0xb6, 0x80, + 0x4e, 0x5c, 0x7a, 0x1c, 0xc9, 0x5c, 0x2d, 0xf4, + 0xde, 0xfc, 0x69, 0x00, 0x85, 0x0a, 0x2c, 0x8b, + 0xad, 0xec, 0x1c, 0x1a, 0xa4, 0x51, 0x6a, 0x8a, + 0x47, 0xbb, 0xbe, 0x73, 0x9b, 0xe7, 0x93, 0xfb, + 0x63, 0x5e, 0xcd, 0xe6, 0x92, 0x8a, 0xef, 0x68, + 0x84, 0x20, 0xa8, 0x33, 0xb5, 0x4f, 0xca, 0x49, + 0x26, 0x54, 0x73, 0xae, 0xca, 0x51, 0x8b, 0x64, + 0xa7, 0x7a, 0x3c, 0x02, 0x0a, 0x76, 0x67, 0xea, + 0x76, 0xdc, 0xcf, 0x1f, 0x85, 0xc5, 0x67, 0xeb, + 0xbd, 0x94, 0x48, 0x08, 0xbb, 0x17, 0x52, 0x27, + 0xd8, 0x28, 0x21, 0x39, 0x93, 0xe8, 0x03, 0x01, +}; + +const vsc_data_t test_data_message_info_RSA2048_PRIVATE_KEY = { + RSA2048_PRIVATE_KEY, sizeof(RSA2048_PRIVATE_KEY) +}; + +static const byte MESSAGE_INFO_WITH_ONE_RSA2048_RECIPIENT[] = { + 0x30, 0x82, 0x01, 0x87, 0x02, 0x01, 0x00, 0x30, + 0x82, 0x01, 0x80, 0x06, 0x09, 0x2A, 0x86, 0x48, + 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x03, 0xA0, 0x82, + 0x01, 0x71, 0x30, 0x82, 0x01, 0x6D, 0x02, 0x01, + 0x02, 0x31, 0x82, 0x01, 0x3E, 0x30, 0x82, 0x01, + 0x3A, 0x02, 0x01, 0x02, 0xA0, 0x22, 0x04, 0x20, + 0xE9, 0x5F, 0x12, 0x2C, 0x87, 0x2B, 0x54, 0x85, + 0x85, 0x3F, 0xDF, 0x9C, 0xF3, 0x73, 0x9A, 0x9F, + 0x4E, 0xBF, 0xC3, 0x6C, 0x95, 0xF5, 0x7B, 0x69, + 0x1F, 0x4A, 0xE8, 0x87, 0x18, 0xD4, 0x21, 0xD8, + 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, + 0x82, 0x01, 0x00, 0x3A, 0xA7, 0xC3, 0xD0, 0x12, + 0xBC, 0x4E, 0x29, 0xBF, 0xA9, 0x96, 0xF7, 0xFB, + 0xD8, 0x1E, 0x74, 0xB7, 0x30, 0x3E, 0xCD, 0xEB, + 0xBA, 0xA4, 0x1D, 0xD6, 0x34, 0x6D, 0x2A, 0x81, + 0x86, 0x52, 0x7C, 0x22, 0xF8, 0x69, 0x22, 0x3A, + 0xBE, 0x85, 0x65, 0xC5, 0xF0, 0x4F, 0x34, 0x84, + 0x05, 0xCE, 0x0A, 0xA6, 0xF0, 0x0D, 0x27, 0xF6, + 0x15, 0xA1, 0x70, 0xB0, 0x63, 0xDF, 0x3F, 0xB5, + 0x95, 0x2B, 0x06, 0x87, 0x7E, 0xCF, 0xC4, 0x88, + 0xBE, 0x1A, 0x63, 0xC0, 0xE5, 0x05, 0x79, 0x2D, + 0x07, 0x24, 0x77, 0x69, 0x3D, 0x16, 0xEF, 0xA3, + 0x54, 0xB2, 0xD6, 0x59, 0xED, 0x4F, 0xDB, 0x07, + 0xC4, 0x63, 0xA2, 0xF9, 0xC0, 0x0D, 0x0D, 0xF5, + 0x51, 0x14, 0x1D, 0x38, 0x5F, 0xC9, 0x7F, 0x15, + 0x5E, 0x24, 0xDC, 0xC2, 0x08, 0x04, 0x33, 0xD7, + 0xD1, 0x5C, 0x1C, 0xF7, 0x6E, 0xFF, 0xA1, 0x19, + 0x3F, 0x50, 0x1F, 0x27, 0x8D, 0x8D, 0xC2, 0xE3, + 0x8F, 0x0E, 0x60, 0xD5, 0x2C, 0x34, 0x2F, 0xE8, + 0x2F, 0x18, 0xA2, 0xA9, 0xEB, 0xA0, 0x6B, 0xEB, + 0x7C, 0x96, 0x6F, 0x13, 0xF8, 0x9B, 0xC5, 0x3A, + 0xA6, 0x37, 0x56, 0x7D, 0x7D, 0x6B, 0xE4, 0x52, + 0xBA, 0x5A, 0x87, 0xE6, 0x06, 0xE0, 0x42, 0xE8, + 0x5F, 0x03, 0x50, 0x84, 0xA2, 0x44, 0x76, 0x1B, + 0xA5, 0x72, 0xA9, 0x3F, 0x03, 0x5F, 0x4C, 0x83, + 0xF6, 0xDD, 0x59, 0x2A, 0xB1, 0x77, 0x0D, 0x2B, + 0xAE, 0xAB, 0x1F, 0x9D, 0x51, 0x9E, 0x7E, 0x5E, + 0xE4, 0xDC, 0xBA, 0xE2, 0x49, 0x6A, 0xEB, 0x3C, + 0x01, 0x97, 0x02, 0x1C, 0xF2, 0x65, 0xC8, 0xDB, + 0x3D, 0x69, 0xCB, 0x28, 0xF9, 0x77, 0xF3, 0xAA, + 0xCF, 0x25, 0x4D, 0xCF, 0x4E, 0xA3, 0x7A, 0x4D, + 0x78, 0x49, 0xAE, 0x09, 0x14, 0xE0, 0xDF, 0x2A, + 0x2F, 0xFF, 0x2F, 0xF5, 0x5B, 0x58, 0xD5, 0x15, + 0xD6, 0x6F, 0x82, 0x30, 0x26, 0x06, 0x09, 0x2A, + 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01, + 0x30, 0x19, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x01, 0x2E, 0x04, 0x0C, 0xDE, + 0xF7, 0x1F, 0x7E, 0x41, 0xB7, 0x49, 0x7D, 0x72, + 0xEE, 0xD9, 0x72 +}; + +const vsc_data_t test_data_message_info_MESSAGE_INFO_WITH_ONE_RSA2048_RECIPIENT = { + MESSAGE_INFO_WITH_ONE_RSA2048_RECIPIENT, sizeof(MESSAGE_INFO_WITH_ONE_RSA2048_RECIPIENT) +}; + + +static const byte ED25519_RECIPIENT_ID[] = { + 0x6A, 0x07, 0x82, 0x58, 0xDF, 0x74, 0x4E, 0x6A, + 0x91, 0xEF, 0x00, 0x40, 0x57, 0xFA, 0xA4, 0xB2, + 0x4D, 0x33, 0x9F, 0xB1, 0xC0, 0x3D, 0x6C, 0x19, + 0xC5, 0xED, 0x52, 0xEB, 0xB5, 0x20, 0xA3, 0xB4, +}; + +const vsc_data_t test_data_message_info_ED25519_RECIPIENT_ID = { + ED25519_RECIPIENT_ID, sizeof(ED25519_RECIPIENT_ID) +}; + +static const byte ED25519_PUBLIC_KEY[] = { + 0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, + 0x70, 0x03, 0x21, 0x00, 0x86, 0x61, 0x40, 0x74, + 0xb7, 0xa5, 0xd1, 0x13, 0x04, 0x48, 0xbe, 0x69, + 0xa4, 0xa2, 0x5c, 0xe5, 0x8d, 0xbf, 0x76, 0x0a, + 0x87, 0xbb, 0xf9, 0x2a, 0x03, 0xad, 0xd9, 0x73, + 0xf3, 0x8e, 0xce, 0x7c +}; + +const vsc_data_t test_data_message_info_ED25519_PUBLIC_KEY = { + ED25519_PUBLIC_KEY, sizeof(ED25519_PUBLIC_KEY) +}; + +static const byte ED25519_PRIVATE_KEY[] = { + 0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, + 0x03, 0x2b, 0x65, 0x70, 0x04, 0x22, 0x04, 0x20, + 0x10, 0xda, 0x87, 0x56, 0x6b, 0x44, 0x6e, 0xdb, + 0x74, 0xaf, 0xa6, 0xeb, 0x67, 0x54, 0x77, 0x43, + 0x67, 0x08, 0x1e, 0xfa, 0x5f, 0xcd, 0x39, 0xc1, + 0x9e, 0x64, 0xa3, 0x68, 0x30, 0x44, 0x5b, 0x1b, +}; + +const vsc_data_t test_data_message_info_ED25519_PRIVATE_KEY = { + ED25519_PRIVATE_KEY, sizeof(ED25519_PRIVATE_KEY) +}; + +static const byte MESSAGE_INFO_WITH_ONE_ED25519_RECIPIENT[] = { + 0x30, 0x82, 0x01, 0x60, 0x02, 0x01, 0x00, 0x30, + 0x82, 0x01, 0x59, 0x06, 0x09, 0x2A, 0x86, 0x48, + 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x03, 0xA0, 0x82, + 0x01, 0x4A, 0x30, 0x82, 0x01, 0x46, 0x02, 0x01, + 0x02, 0x31, 0x82, 0x01, 0x17, 0x30, 0x82, 0x01, + 0x13, 0x02, 0x01, 0x02, 0xA0, 0x22, 0x04, 0x20, + 0x6A, 0x07, 0x82, 0x58, 0xDF, 0x74, 0x4E, 0x6A, + 0x91, 0xEF, 0x00, 0x40, 0x57, 0xFA, 0xA4, 0xB2, + 0x4D, 0x33, 0x9F, 0xB1, 0xC0, 0x3D, 0x6C, 0x19, + 0xC5, 0xED, 0x52, 0xEB, 0xB5, 0x20, 0xA3, 0xB4, + 0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, 0x70, 0x04, + 0x81, 0xE2, 0x30, 0x81, 0xDF, 0x02, 0x01, 0x00, + 0x30, 0x2A, 0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, + 0x70, 0x03, 0x21, 0x00, 0xEB, 0xD4, 0x96, 0x10, + 0xEA, 0xE7, 0x29, 0x91, 0x00, 0x30, 0x3B, 0x9F, + 0xEB, 0x24, 0x13, 0x01, 0x50, 0xE5, 0xEC, 0xF5, + 0xA3, 0xB9, 0xED, 0x0C, 0xD0, 0x06, 0x2C, 0x87, + 0xBF, 0xEE, 0xC3, 0x19, 0x30, 0x18, 0x06, 0x07, + 0x28, 0x81, 0x8C, 0x71, 0x02, 0x05, 0x02, 0x30, + 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, + 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x30, 0x41, + 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, + 0x30, 0xD3, 0x2F, 0xD5, 0xC5, 0x15, 0x63, 0xBF, + 0xB5, 0x85, 0xBC, 0xC4, 0x24, 0x22, 0x40, 0xA7, + 0x70, 0x22, 0x4E, 0xAF, 0xD3, 0xBF, 0xDF, 0xB7, + 0x6C, 0x24, 0xA6, 0x6E, 0x6A, 0x74, 0x23, 0x58, + 0xE2, 0xE2, 0x26, 0x8F, 0x2D, 0xD5, 0x16, 0xC5, + 0x3F, 0xF3, 0xCD, 0xA4, 0x3C, 0x1D, 0x2F, 0x63, + 0x9D, 0x30, 0x51, 0x30, 0x1D, 0x06, 0x09, 0x60, + 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2A, + 0x04, 0x10, 0xF2, 0x97, 0x47, 0xF4, 0x25, 0x18, + 0x68, 0x55, 0xBA, 0x72, 0xAB, 0xD4, 0xAC, 0x0A, + 0x47, 0xEA, 0x04, 0x30, 0x37, 0xE4, 0xA8, 0xD6, + 0xD6, 0x41, 0x5D, 0x6E, 0x8A, 0x5E, 0xDD, 0xD2, + 0x5C, 0xC1, 0x37, 0x92, 0x86, 0x4E, 0xCD, 0x77, + 0x11, 0xE5, 0x25, 0xB2, 0x3E, 0xFC, 0xC9, 0x66, + 0x73, 0x2F, 0x39, 0xA8, 0x7B, 0x9F, 0x1A, 0x67, + 0xEC, 0xEE, 0x7A, 0xB3, 0x73, 0x41, 0xC9, 0x08, + 0xAA, 0xCD, 0x71, 0x4B, 0x30, 0x26, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, + 0x01, 0x30, 0x19, 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x01, 0x2E, 0x04, 0x0C, + 0xDE, 0xF7, 0x1F, 0x7E, 0x41, 0xB7, 0x49, 0x7D, + 0x72, 0xEE, 0xD9, 0x72 +}; + +const vsc_data_t test_data_message_info_MESSAGE_INFO_WITH_ONE_ED25519_RECIPIENT = { + MESSAGE_INFO_WITH_ONE_ED25519_RECIPIENT, sizeof(MESSAGE_INFO_WITH_ONE_ED25519_RECIPIENT) +}; + + +static const byte MESSAGE_INFO_WITH_ONE_ED25519_RECIPIENT_AND_ONE_RSA2048_RECIPIENT[] = { + 0x30, 0x82, 0x02, 0x9E, 0x02, 0x01, 0x00, 0x30, + 0x82, 0x02, 0x97, 0x06, 0x09, 0x2A, 0x86, 0x48, + 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x03, 0xA0, 0x82, + 0x02, 0x88, 0x30, 0x82, 0x02, 0x84, 0x02, 0x01, + 0x02, 0x31, 0x82, 0x02, 0x55, 0x30, 0x82, 0x01, + 0x13, 0x02, 0x01, 0x02, 0xA0, 0x22, 0x04, 0x20, + 0x6A, 0x07, 0x82, 0x58, 0xDF, 0x74, 0x4E, 0x6A, + 0x91, 0xEF, 0x00, 0x40, 0x57, 0xFA, 0xA4, 0xB2, + 0x4D, 0x33, 0x9F, 0xB1, 0xC0, 0x3D, 0x6C, 0x19, + 0xC5, 0xED, 0x52, 0xEB, 0xB5, 0x20, 0xA3, 0xB4, + 0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, 0x70, 0x04, + 0x81, 0xE2, 0x30, 0x81, 0xDF, 0x02, 0x01, 0x00, + 0x30, 0x2A, 0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, + 0x70, 0x03, 0x21, 0x00, 0xEB, 0xD4, 0x96, 0x10, + 0xEA, 0xE7, 0x29, 0x91, 0x00, 0x30, 0x3B, 0x9F, + 0xEB, 0x24, 0x13, 0x01, 0x50, 0xE5, 0xEC, 0xF5, + 0xA3, 0xB9, 0xED, 0x0C, 0xD0, 0x06, 0x2C, 0x87, + 0xBF, 0xEE, 0xC3, 0x19, 0x30, 0x18, 0x06, 0x07, + 0x28, 0x81, 0x8C, 0x71, 0x02, 0x05, 0x02, 0x30, + 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, + 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x30, 0x41, + 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, + 0x30, 0xD3, 0x2F, 0xD5, 0xC5, 0x15, 0x63, 0xBF, + 0xB5, 0x85, 0xBC, 0xC4, 0x24, 0x22, 0x40, 0xA7, + 0x70, 0x22, 0x4E, 0xAF, 0xD3, 0xBF, 0xDF, 0xB7, + 0x6C, 0x24, 0xA6, 0x6E, 0x6A, 0x74, 0x23, 0x58, + 0xE2, 0xE2, 0x26, 0x8F, 0x2D, 0xD5, 0x16, 0xC5, + 0x3F, 0xF3, 0xCD, 0xA4, 0x3C, 0x1D, 0x2F, 0x63, + 0x9D, 0x30, 0x51, 0x30, 0x1D, 0x06, 0x09, 0x60, + 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2A, + 0x04, 0x10, 0xF2, 0x97, 0x47, 0xF4, 0x25, 0x18, + 0x68, 0x55, 0xBA, 0x72, 0xAB, 0xD4, 0xAC, 0x0A, + 0x47, 0xEA, 0x04, 0x30, 0x37, 0xE4, 0xA8, 0xD6, + 0xD6, 0x41, 0x5D, 0x6E, 0x8A, 0x5E, 0xDD, 0xD2, + 0x5C, 0xC1, 0x37, 0x92, 0x86, 0x4E, 0xCD, 0x77, + 0x11, 0xE5, 0x25, 0xB2, 0x3E, 0xFC, 0xC9, 0x66, + 0x73, 0x2F, 0x39, 0xA8, 0x7B, 0x9F, 0x1A, 0x67, + 0xEC, 0xEE, 0x7A, 0xB3, 0x73, 0x41, 0xC9, 0x08, + 0xAA, 0xCD, 0x71, 0x4B, 0x30, 0x82, 0x01, 0x3A, + 0x02, 0x01, 0x02, 0xA0, 0x22, 0x04, 0x20, 0xE9, + 0x5F, 0x12, 0x2C, 0x87, 0x2B, 0x54, 0x85, 0x85, + 0x3F, 0xDF, 0x9C, 0xF3, 0x73, 0x9A, 0x9F, 0x4E, + 0xBF, 0xC3, 0x6C, 0x95, 0xF5, 0x7B, 0x69, 0x1F, + 0x4A, 0xE8, 0x87, 0x18, 0xD4, 0x21, 0xD8, 0x30, + 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, + 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, + 0x01, 0x00, 0x3A, 0xA7, 0xC3, 0xD0, 0x12, 0xBC, + 0x4E, 0x29, 0xBF, 0xA9, 0x96, 0xF7, 0xFB, 0xD8, + 0x1E, 0x74, 0xB7, 0x30, 0x3E, 0xCD, 0xEB, 0xBA, + 0xA4, 0x1D, 0xD6, 0x34, 0x6D, 0x2A, 0x81, 0x86, + 0x52, 0x7C, 0x22, 0xF8, 0x69, 0x22, 0x3A, 0xBE, + 0x85, 0x65, 0xC5, 0xF0, 0x4F, 0x34, 0x84, 0x05, + 0xCE, 0x0A, 0xA6, 0xF0, 0x0D, 0x27, 0xF6, 0x15, + 0xA1, 0x70, 0xB0, 0x63, 0xDF, 0x3F, 0xB5, 0x95, + 0x2B, 0x06, 0x87, 0x7E, 0xCF, 0xC4, 0x88, 0xBE, + 0x1A, 0x63, 0xC0, 0xE5, 0x05, 0x79, 0x2D, 0x07, + 0x24, 0x77, 0x69, 0x3D, 0x16, 0xEF, 0xA3, 0x54, + 0xB2, 0xD6, 0x59, 0xED, 0x4F, 0xDB, 0x07, 0xC4, + 0x63, 0xA2, 0xF9, 0xC0, 0x0D, 0x0D, 0xF5, 0x51, + 0x14, 0x1D, 0x38, 0x5F, 0xC9, 0x7F, 0x15, 0x5E, + 0x24, 0xDC, 0xC2, 0x08, 0x04, 0x33, 0xD7, 0xD1, + 0x5C, 0x1C, 0xF7, 0x6E, 0xFF, 0xA1, 0x19, 0x3F, + 0x50, 0x1F, 0x27, 0x8D, 0x8D, 0xC2, 0xE3, 0x8F, + 0x0E, 0x60, 0xD5, 0x2C, 0x34, 0x2F, 0xE8, 0x2F, + 0x18, 0xA2, 0xA9, 0xEB, 0xA0, 0x6B, 0xEB, 0x7C, + 0x96, 0x6F, 0x13, 0xF8, 0x9B, 0xC5, 0x3A, 0xA6, + 0x37, 0x56, 0x7D, 0x7D, 0x6B, 0xE4, 0x52, 0xBA, + 0x5A, 0x87, 0xE6, 0x06, 0xE0, 0x42, 0xE8, 0x5F, + 0x03, 0x50, 0x84, 0xA2, 0x44, 0x76, 0x1B, 0xA5, + 0x72, 0xA9, 0x3F, 0x03, 0x5F, 0x4C, 0x83, 0xF6, + 0xDD, 0x59, 0x2A, 0xB1, 0x77, 0x0D, 0x2B, 0xAE, + 0xAB, 0x1F, 0x9D, 0x51, 0x9E, 0x7E, 0x5E, 0xE4, + 0xDC, 0xBA, 0xE2, 0x49, 0x6A, 0xEB, 0x3C, 0x01, + 0x97, 0x02, 0x1C, 0xF2, 0x65, 0xC8, 0xDB, 0x3D, + 0x69, 0xCB, 0x28, 0xF9, 0x77, 0xF3, 0xAA, 0xCF, + 0x25, 0x4D, 0xCF, 0x4E, 0xA3, 0x7A, 0x4D, 0x78, + 0x49, 0xAE, 0x09, 0x14, 0xE0, 0xDF, 0x2A, 0x2F, + 0xFF, 0x2F, 0xF5, 0x5B, 0x58, 0xD5, 0x15, 0xD6, + 0x6F, 0x82, 0x30, 0x26, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01, 0x30, + 0x19, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, + 0x03, 0x04, 0x01, 0x2E, 0x04, 0x0C, 0xDE, 0xF7, + 0x1F, 0x7E, 0x41, 0xB7, 0x49, 0x7D, 0x72, 0xEE, + 0xD9, 0x72 +}; + +const vsc_data_t test_data_message_info_MESSAGE_INFO_WITH_ONE_ED25519_RECIPIENT_AND_ONE_RSA2048_RECIPIENT = { + MESSAGE_INFO_WITH_ONE_ED25519_RECIPIENT_AND_ONE_RSA2048_RECIPIENT, + sizeof(MESSAGE_INFO_WITH_ONE_ED25519_RECIPIENT_AND_ONE_RSA2048_RECIPIENT) +}; + diff --git a/tests/foundation/test_message_info_editor.c b/tests/foundation/test_message_info_editor.c new file mode 100644 index 000000000..c3feb2b7e --- /dev/null +++ b/tests/foundation/test_message_info_editor.c @@ -0,0 +1,266 @@ +// Copyright (C) 2015-2019 Virgil Security, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// (1) Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// (2) Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// (3) Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Lead Maintainer: Virgil Security Inc. + + +#define UNITY_BEGIN() UnityBegin(__FILENAME__) + +#include "unity.h" +#include "test_utils.h" + + +#define TEST_DEPENDENCIES_AVAILABLE \ + (VSCF_RECIPIENT_CIPHER && VSCF_ALG_FACTORY && VSCF_KEY_PROVIDER && VSCF_ED25519 && VSCF_RSA) +#if TEST_DEPENDENCIES_AVAILABLE + +#include "vscf_fake_random.h" +#include "vscf_key_provider.h" +#include "vscf_message_info_editor.h" + +#include "test_data_message_info.h" +#include "test_data_recipient_cipher.h" + +void +test__add_key_recipient__rsa2048_to_message_info_with_ed25519__correct(void) { + // + // Prepare helpers. + // + vscf_error_t error; + vscf_error_reset(&error); + + vscf_fake_random_t *fake_random = vscf_fake_random_new(); + vscf_fake_random_setup_source_byte(fake_random, 0xAB); + + vscf_key_provider_t *key_provider = vscf_key_provider_new(); + vscf_key_provider_use_random(key_provider, vscf_fake_random_impl(fake_random)); + TEST_ASSERT_EQUAL(vscf_status_SUCCESS, vscf_key_provider_setup_defaults(key_provider)); + + vscf_message_info_editor_t *message_info_editor = vscf_message_info_editor_new(); + vscf_message_info_editor_use_random(message_info_editor, vscf_fake_random_impl(fake_random)); + + // + // Prepare recipients. + // + vscf_impl_t *ed25519_private_key = + vscf_key_provider_import_private_key(key_provider, test_data_message_info_ED25519_PRIVATE_KEY, &error); + TEST_ASSERT_EQUAL(vscf_status_SUCCESS, vscf_error_status(&error)); + + vscf_impl_t *rsa2048_public_key = + vscf_key_provider_import_public_key(key_provider, test_data_message_info_RSA2048_PUBLIC_KEY, &error); + TEST_ASSERT_EQUAL(vscf_status_SUCCESS, vscf_error_status(&error)); + + // + // Unpack + // + vscf_status_t status = vscf_message_info_editor_unpack(message_info_editor, + test_data_message_info_MESSAGE_INFO_WITH_ONE_ED25519_RECIPIENT, test_data_message_info_ED25519_RECIPIENT_ID, + ed25519_private_key); + TEST_ASSERT_EQUAL(vscf_status_SUCCESS, status); + + // + // Add new recipient + // + status = vscf_message_info_editor_add_key_recipient( + message_info_editor, test_data_message_info_RSA2048_RECIPIENT_ID, rsa2048_public_key); + TEST_ASSERT_EQUAL(vscf_status_SUCCESS, status); + + // + // Pack + // + vsc_buffer_t *new_packed_message_info = + vsc_buffer_new_with_capacity(vscf_message_info_editor_packed_len(message_info_editor)); + vscf_message_info_editor_pack(message_info_editor, new_packed_message_info); + + // + // Check + // + TEST_ASSERT_EQUAL_DATA_AND_BUFFER( + test_data_message_info_MESSAGE_INFO_WITH_ONE_ED25519_RECIPIENT_AND_ONE_RSA2048_RECIPIENT, + new_packed_message_info); + + // + // Cleanup + // + vsc_buffer_destroy(&new_packed_message_info); + vscf_impl_destroy(&rsa2048_public_key); + vscf_impl_destroy(&ed25519_private_key); + vscf_message_info_editor_destroy(&message_info_editor); + vscf_key_provider_destroy(&key_provider); + vscf_fake_random_destroy(&fake_random); +} + +void +test__remove_key_recipient__ed25519_from_message_info_with_ed25519_and_rsa2048__correct(void) { + // + // Prepare helpers. + // + vscf_error_t error; + vscf_error_reset(&error); + + vscf_fake_random_t *fake_random = vscf_fake_random_new(); + vscf_fake_random_setup_source_byte(fake_random, 0xAB); + + vscf_key_provider_t *key_provider = vscf_key_provider_new(); + vscf_key_provider_use_random(key_provider, vscf_fake_random_impl(fake_random)); + TEST_ASSERT_EQUAL(vscf_status_SUCCESS, vscf_key_provider_setup_defaults(key_provider)); + + vscf_message_info_editor_t *message_info_editor = vscf_message_info_editor_new(); + vscf_message_info_editor_use_random(message_info_editor, vscf_fake_random_impl(fake_random)); + + // + // Prepare recipients. + // + vscf_impl_t *rsa2048_private_key = + vscf_key_provider_import_private_key(key_provider, test_data_message_info_RSA2048_PRIVATE_KEY, &error); + TEST_ASSERT_EQUAL(vscf_status_SUCCESS, vscf_error_status(&error)); + + // + // Unpack + // + vscf_status_t status = vscf_message_info_editor_unpack(message_info_editor, + test_data_message_info_MESSAGE_INFO_WITH_ONE_ED25519_RECIPIENT_AND_ONE_RSA2048_RECIPIENT, + test_data_message_info_RSA2048_RECIPIENT_ID, rsa2048_private_key); + TEST_ASSERT_EQUAL(vscf_status_SUCCESS, status); + + // + // Remove recipient + // + bool was_removed = vscf_message_info_editor_remove_key_recipient( + message_info_editor, test_data_message_info_ED25519_RECIPIENT_ID); + TEST_ASSERT_TRUE(was_removed); + + // + // Pack + // + vsc_buffer_t *new_packed_message_info = + vsc_buffer_new_with_capacity(vscf_message_info_editor_packed_len(message_info_editor)); + vscf_message_info_editor_pack(message_info_editor, new_packed_message_info); + + // + // Check + // + TEST_ASSERT_EQUAL_DATA_AND_BUFFER( + test_data_message_info_MESSAGE_INFO_WITH_ONE_RSA2048_RECIPIENT, new_packed_message_info); + + // + // Cleanup + // + vsc_buffer_destroy(&new_packed_message_info); + vscf_impl_destroy(&rsa2048_private_key); + vscf_message_info_editor_destroy(&message_info_editor); + vscf_key_provider_destroy(&key_provider); + vscf_fake_random_destroy(&fake_random); +} + +void +test__remove_key_recipient__rsa2048_from_message_info_with_ed25519_and_rsa2048__correct(void) { + // + // Prepare helpers. + // + vscf_error_t error; + vscf_error_reset(&error); + + vscf_fake_random_t *fake_random = vscf_fake_random_new(); + vscf_fake_random_setup_source_byte(fake_random, 0xAB); + + vscf_key_provider_t *key_provider = vscf_key_provider_new(); + vscf_key_provider_use_random(key_provider, vscf_fake_random_impl(fake_random)); + TEST_ASSERT_EQUAL(vscf_status_SUCCESS, vscf_key_provider_setup_defaults(key_provider)); + + vscf_message_info_editor_t *message_info_editor = vscf_message_info_editor_new(); + vscf_message_info_editor_use_random(message_info_editor, vscf_fake_random_impl(fake_random)); + + // + // Prepare recipients. + // + vscf_impl_t *ed25519_private_key = + vscf_key_provider_import_private_key(key_provider, test_data_message_info_ED25519_PRIVATE_KEY, &error); + TEST_ASSERT_EQUAL(vscf_status_SUCCESS, vscf_error_status(&error)); + + // + // Unpack + // + vscf_status_t status = vscf_message_info_editor_unpack(message_info_editor, + test_data_message_info_MESSAGE_INFO_WITH_ONE_ED25519_RECIPIENT_AND_ONE_RSA2048_RECIPIENT, + test_data_message_info_ED25519_RECIPIENT_ID, ed25519_private_key); + TEST_ASSERT_EQUAL(vscf_status_SUCCESS, status); + + // + // Remove recipient + // + bool was_removed = vscf_message_info_editor_remove_key_recipient( + message_info_editor, test_data_message_info_RSA2048_RECIPIENT_ID); + TEST_ASSERT_TRUE(was_removed); + + // + // Pack + // + vsc_buffer_t *new_packed_message_info = + vsc_buffer_new_with_capacity(vscf_message_info_editor_packed_len(message_info_editor)); + vscf_message_info_editor_pack(message_info_editor, new_packed_message_info); + + // + // Check + // + TEST_ASSERT_EQUAL_DATA_AND_BUFFER( + test_data_message_info_MESSAGE_INFO_WITH_ONE_ED25519_RECIPIENT, new_packed_message_info); + + // + // Cleanup + // + vsc_buffer_destroy(&new_packed_message_info); + vscf_impl_destroy(&ed25519_private_key); + vscf_message_info_editor_destroy(&message_info_editor); + vscf_key_provider_destroy(&key_provider); + vscf_fake_random_destroy(&fake_random); +} + +#endif + +// -------------------------------------------------------------------------- +// Entrypoint. +// -------------------------------------------------------------------------- +int +main(void) { + UNITY_BEGIN(); + +#if TEST_DEPENDENCIES_AVAILABLE + RUN_TEST(test__add_key_recipient__rsa2048_to_message_info_with_ed25519__correct); + RUN_TEST(test__remove_key_recipient__ed25519_from_message_info_with_ed25519_and_rsa2048__correct); + RUN_TEST(test__remove_key_recipient__rsa2048_from_message_info_with_ed25519_and_rsa2048__correct); +#else + RUN_TEST(test__nothing__feature_disabled__must_be_ignored); +#endif + + return UNITY_END(); +} diff --git a/wrappers/java/foundation/jni/FoundationJNI.c b/wrappers/java/foundation/jni/FoundationJNI.c index 6a916299d..9d44cc91d 100644 --- a/wrappers/java/foundation/jni/FoundationJNI.c +++ b/wrappers/java/foundation/jni/FoundationJNI.c @@ -4156,6 +4156,150 @@ JNIEXPORT jobject JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJN return ret; } +JNIEXPORT jlong JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_messageInfoEditor_1new__ (JNIEnv *jenv, jobject jobj) { + jlong c_ctx = 0; + *(vscf_message_info_editor_t **)&c_ctx = vscf_message_info_editor_new(); + return c_ctx; +} + +JNIEXPORT void JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_messageInfoEditor_1close (JNIEnv *jenv, jobject jobj, jlong c_ctx) { + vscf_message_info_editor_delete(*(vscf_message_info_editor_t /*2*/ **) &c_ctx /*5*/); +} + +JNIEXPORT void JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_messageInfoEditor_1setRandom (JNIEnv *jenv, jobject jobj, jlong c_ctx, jobject jrandom) { + jclass random_cls = (*jenv)->GetObjectClass(jenv, jrandom); + if (NULL == random_cls) { + VSCF_ASSERT("Class Random not found."); + } + jfieldID random_fidCtx = (*jenv)->GetFieldID(jenv, random_cls, "cCtx", "J"); + if (NULL == random_fidCtx) { + VSCF_ASSERT("Class 'Random' has no field 'cCtx'."); + } + jlong random_c_ctx = (*jenv)->GetLongField(jenv, jrandom, random_fidCtx); + vscf_impl_t */*6*/ random = *(vscf_impl_t */*6*/*) &random_c_ctx; + + vscf_message_info_editor_release_random((vscf_message_info_editor_t /*2*/ *) c_ctx); + vscf_message_info_editor_use_random((vscf_message_info_editor_t /*2*/ *) c_ctx, random); +} + +JNIEXPORT void JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_messageInfoEditor_1setupDefaults (JNIEnv *jenv, jobject jobj, jlong c_ctx) { + // Cast class context + vscf_message_info_editor_t /*2*/* message_info_editor_ctx = *(vscf_message_info_editor_t /*2*/**) &c_ctx; + + vscf_status_t status = vscf_message_info_editor_setup_defaults(message_info_editor_ctx /*a1*/); + if (status != vscf_status_SUCCESS) { + throwFoundationException(jenv, jobj, status); + return; + } +} + +JNIEXPORT void JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_messageInfoEditor_1unpack (JNIEnv *jenv, jobject jobj, jlong c_ctx, jbyteArray jmessageInfoData, jbyteArray jownerRecipientId, jobject jownerPrivateKey) { + // Cast class context + vscf_message_info_editor_t /*2*/* message_info_editor_ctx = *(vscf_message_info_editor_t /*2*/**) &c_ctx; + // Wrap Java interfaces + jclass owner_private_key_cls = (*jenv)->GetObjectClass(jenv, jownerPrivateKey); + if (NULL == owner_private_key_cls) { + VSCF_ASSERT("Class PrivateKey not found."); + } + jfieldID owner_private_key_fidCtx = (*jenv)->GetFieldID(jenv, owner_private_key_cls, "cCtx", "J"); + if (NULL == owner_private_key_fidCtx) { + VSCF_ASSERT("Class 'PrivateKey' has no field 'cCtx'."); + } + jlong owner_private_key_c_ctx = (*jenv)->GetLongField(jenv, jownerPrivateKey, owner_private_key_fidCtx); + vscf_impl_t */*6*/ owner_private_key = *(vscf_impl_t */*6*/*)&owner_private_key_c_ctx; + + // Wrap input data + byte* message_info_data_arr = (byte*) (*jenv)->GetByteArrayElements(jenv, jmessageInfoData, NULL); + vsc_data_t message_info_data = vsc_data(message_info_data_arr, (*jenv)->GetArrayLength(jenv, jmessageInfoData)); + + byte* owner_recipient_id_arr = (byte*) (*jenv)->GetByteArrayElements(jenv, jownerRecipientId, NULL); + vsc_data_t owner_recipient_id = vsc_data(owner_recipient_id_arr, (*jenv)->GetArrayLength(jenv, jownerRecipientId)); + + vscf_status_t status = vscf_message_info_editor_unpack(message_info_editor_ctx /*a1*/, message_info_data /*a3*/, owner_recipient_id /*a3*/, owner_private_key /*a6*/); + if (status != vscf_status_SUCCESS) { + throwFoundationException(jenv, jobj, status); + return; + } + // Free resources + (*jenv)->ReleaseByteArrayElements(jenv, jmessageInfoData, (jbyte*) message_info_data_arr, 0); + + (*jenv)->ReleaseByteArrayElements(jenv, jownerRecipientId, (jbyte*) owner_recipient_id_arr, 0); +} + +JNIEXPORT void JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_messageInfoEditor_1addKeyRecipient (JNIEnv *jenv, jobject jobj, jlong c_ctx, jbyteArray jrecipientId, jobject jpublicKey) { + // Cast class context + vscf_message_info_editor_t /*2*/* message_info_editor_ctx = *(vscf_message_info_editor_t /*2*/**) &c_ctx; + // Wrap Java interfaces + jclass public_key_cls = (*jenv)->GetObjectClass(jenv, jpublicKey); + if (NULL == public_key_cls) { + VSCF_ASSERT("Class PublicKey not found."); + } + jfieldID public_key_fidCtx = (*jenv)->GetFieldID(jenv, public_key_cls, "cCtx", "J"); + if (NULL == public_key_fidCtx) { + VSCF_ASSERT("Class 'PublicKey' has no field 'cCtx'."); + } + jlong public_key_c_ctx = (*jenv)->GetLongField(jenv, jpublicKey, public_key_fidCtx); + vscf_impl_t */*6*/ public_key = *(vscf_impl_t */*6*/*)&public_key_c_ctx; + + // Wrap input data + byte* recipient_id_arr = (byte*) (*jenv)->GetByteArrayElements(jenv, jrecipientId, NULL); + vsc_data_t recipient_id = vsc_data(recipient_id_arr, (*jenv)->GetArrayLength(jenv, jrecipientId)); + + vscf_status_t status = vscf_message_info_editor_add_key_recipient(message_info_editor_ctx /*a1*/, recipient_id /*a3*/, public_key /*a6*/); + if (status != vscf_status_SUCCESS) { + throwFoundationException(jenv, jobj, status); + return; + } + // Free resources + (*jenv)->ReleaseByteArrayElements(jenv, jrecipientId, (jbyte*) recipient_id_arr, 0); +} + +JNIEXPORT jboolean JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_messageInfoEditor_1removeKeyRecipient (JNIEnv *jenv, jobject jobj, jlong c_ctx, jbyteArray jrecipientId) { + // Cast class context + vscf_message_info_editor_t /*2*/* message_info_editor_ctx = *(vscf_message_info_editor_t /*2*/**) &c_ctx; + + // Wrap input data + byte* recipient_id_arr = (byte*) (*jenv)->GetByteArrayElements(jenv, jrecipientId, NULL); + vsc_data_t recipient_id = vsc_data(recipient_id_arr, (*jenv)->GetArrayLength(jenv, jrecipientId)); + + jboolean ret = (jboolean) vscf_message_info_editor_remove_key_recipient(message_info_editor_ctx /*a1*/, recipient_id /*a3*/); + // Free resources + (*jenv)->ReleaseByteArrayElements(jenv, jrecipientId, (jbyte*) recipient_id_arr, 0); + + return ret; +} + +JNIEXPORT void JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_messageInfoEditor_1removeAll (JNIEnv *jenv, jobject jobj, jlong c_ctx) { + // Cast class context + vscf_message_info_editor_t /*2*/* message_info_editor_ctx = *(vscf_message_info_editor_t /*2*/**) &c_ctx; + + vscf_message_info_editor_remove_all(message_info_editor_ctx /*a1*/); +} + +JNIEXPORT jint JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_messageInfoEditor_1packedLen (JNIEnv *jenv, jobject jobj, jlong c_ctx) { + // Cast class context + vscf_message_info_editor_t /*2*/* message_info_editor_ctx = *(vscf_message_info_editor_t /*2*/**) &c_ctx; + + jint ret = (jint) vscf_message_info_editor_packed_len(message_info_editor_ctx /*a1*/); + return ret; +} + +JNIEXPORT jbyteArray JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_messageInfoEditor_1pack (JNIEnv *jenv, jobject jobj, jlong c_ctx) { + // Cast class context + vscf_message_info_editor_t /*2*/* message_info_editor_ctx = *(vscf_message_info_editor_t /*2*/**) &c_ctx; + + // Wrap input buffers + vsc_buffer_t *message_info = vsc_buffer_new_with_capacity(vscf_message_info_editor_packed_len((vscf_message_info_editor_t /*2*/ *) c_ctx /*3*/)); + + vscf_message_info_editor_pack(message_info_editor_ctx /*a1*/, message_info /*a3*/); + jbyteArray ret = (*jenv)->NewByteArray(jenv, vsc_buffer_len(message_info)); + (*jenv)->SetByteArrayRegion (jenv, ret, 0, vsc_buffer_len(message_info), (jbyte*) vsc_buffer_bytes(message_info)); + // Free resources + vsc_buffer_delete(message_info); + + return ret; +} + JNIEXPORT jlong JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_sha224_1new__ (JNIEnv *jenv, jobject jobj) { jlong c_ctx = 0; *(vscf_sha224_t **)&c_ctx = vscf_sha224_new(); diff --git a/wrappers/java/foundation/jni/FoundationJNI.h b/wrappers/java/foundation/jni/FoundationJNI.h index cc466dbe2..579a986a2 100644 --- a/wrappers/java/foundation/jni/FoundationJNI.h +++ b/wrappers/java/foundation/jni/FoundationJNI.h @@ -385,6 +385,26 @@ JNIEXPORT jbyteArray JNICALL Java_com_virgilsecurity_crypto_foundation_Foundatio JNIEXPORT jobject JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_groupSession_1createGroupTicket (JNIEnv *, jobject, jlong); +JNIEXPORT jlong JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_messageInfoEditor_1new__ (JNIEnv *, jobject); + +JNIEXPORT void JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_messageInfoEditor_1close (JNIEnv *, jobject, jlong); + +JNIEXPORT void JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_messageInfoEditor_1setRandom (JNIEnv *, jobject, jlong, jobject); + +JNIEXPORT void JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_messageInfoEditor_1setupDefaults (JNIEnv *, jobject, jlong); + +JNIEXPORT void JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_messageInfoEditor_1unpack (JNIEnv *, jobject, jlong, jbyteArray, jbyteArray, jobject); + +JNIEXPORT void JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_messageInfoEditor_1addKeyRecipient (JNIEnv *, jobject, jlong, jbyteArray, jobject); + +JNIEXPORT jboolean JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_messageInfoEditor_1removeKeyRecipient (JNIEnv *, jobject, jlong, jbyteArray); + +JNIEXPORT void JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_messageInfoEditor_1removeAll (JNIEnv *, jobject, jlong); + +JNIEXPORT jint JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_messageInfoEditor_1packedLen (JNIEnv *, jobject, jlong); + +JNIEXPORT jbyteArray JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_messageInfoEditor_1pack (JNIEnv *, jobject, jlong); + JNIEXPORT jlong JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_sha224_1new__ (JNIEnv *, jobject); JNIEXPORT void JNICALL Java_com_virgilsecurity_crypto_foundation_FoundationJNI_sha224_1close (JNIEnv *, jobject, jlong); diff --git a/wrappers/java/foundation/src/main/java/com/virgilsecurity/crypto/foundation/FoundationJNI.java b/wrappers/java/foundation/src/main/java/com/virgilsecurity/crypto/foundation/FoundationJNI.java index b2c5d4d66..adc9a5f87 100644 --- a/wrappers/java/foundation/src/main/java/com/virgilsecurity/crypto/foundation/FoundationJNI.java +++ b/wrappers/java/foundation/src/main/java/com/virgilsecurity/crypto/foundation/FoundationJNI.java @@ -440,7 +440,7 @@ private FoundationJNI() { /* * Return buffer length required to hold message info returned by the - * "start encryption" method. + * "pack message info" method. * Precondition: all recipients and custom parameters should be set. */ public native int recipientCipher_messageInfoLen(long cCtx); @@ -801,6 +801,50 @@ private FoundationJNI() { */ public native GroupSessionTicket groupSession_createGroupTicket(long cCtx) throws FoundationException; + public native long messageInfoEditor_new(); + + public native void messageInfoEditor_close(long cCtx); + + public native void messageInfoEditor_setRandom(long cCtx, Random random); + + /* + * Set depenencies to it's defaults. + */ + public native void messageInfoEditor_setupDefaults(long cCtx) throws FoundationException; + + /* + * Unpack serialized message info. + */ + public native void messageInfoEditor_unpack(long cCtx, byte[] messageInfoData, byte[] ownerRecipientId, PrivateKey ownerPrivateKey) throws FoundationException; + + /* + * Add recipient defined with id and public key. + */ + public native void messageInfoEditor_addKeyRecipient(long cCtx, byte[] recipientId, PublicKey publicKey) throws FoundationException; + + /* + * Remove recipient with a given id. + * Return false if recipient with given id was not found. + */ + public native boolean messageInfoEditor_removeKeyRecipient(long cCtx, byte[] recipientId); + + /* + * Remove all existent recipients. + */ + public native void messageInfoEditor_removeAll(long cCtx); + + /* + * Return length of serialized message info. + * Actual length can be obtained right after applying changes. + */ + public native int messageInfoEditor_packedLen(long cCtx); + + /* + * Return serialized message info. + * Precondition: this method can be called after "apply". + */ + public native byte[] messageInfoEditor_pack(long cCtx); + public native long sha224_new(); public native void sha224_close(long cCtx); diff --git a/wrappers/java/foundation/src/main/java/com/virgilsecurity/crypto/foundation/MessageInfoEditor.java b/wrappers/java/foundation/src/main/java/com/virgilsecurity/crypto/foundation/MessageInfoEditor.java new file mode 100644 index 000000000..9f6b24b37 --- /dev/null +++ b/wrappers/java/foundation/src/main/java/com/virgilsecurity/crypto/foundation/MessageInfoEditor.java @@ -0,0 +1,132 @@ +/* +* Copyright (C) 2015-2019 Virgil Security, Inc. +* +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are +* met: +* +* (1) Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* (2) Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* (3) Neither the name of the copyright holder nor the names of its +* contributors may be used to endorse or promote products derived from +* this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* +* Lead Maintainer: Virgil Security Inc. +*/ + +package com.virgilsecurity.crypto.foundation; + +/* +* Add and/or remove recipients and it's paramteres within message info. +* +* Usage: +* 1. Unpack binary message info that was obtained from RecipientCipher. +* 2. Add and/or remove key recipients. +* 3. Pack MessagInfo to the binary data. +*/ +public class MessageInfoEditor implements AutoCloseable { + + public long cCtx; + + /* Create underlying C context. */ + public MessageInfoEditor() { + super(); + this.cCtx = FoundationJNI.INSTANCE.messageInfoEditor_new(); + } + + /* Wrap underlying C context. */ + MessageInfoEditor(FoundationContextHolder contextHolder) { + this.cCtx = contextHolder.cCtx; + } + + /* + * Acquire C context. + * Note. This method is used in generated code only, and SHOULD NOT be used in another way. + */ + public static MessageInfoEditor getInstance(long cCtx) { + FoundationContextHolder ctxHolder = new FoundationContextHolder(cCtx); + return new MessageInfoEditor(ctxHolder); + } + + /* Close resource. */ + public void close() { + FoundationJNI.INSTANCE.messageInfoEditor_close(this.cCtx); + } + + public void setRandom(Random random) { + FoundationJNI.INSTANCE.messageInfoEditor_setRandom(this.cCtx, random); + } + + /* + * Set depenencies to it's defaults. + */ + public void setupDefaults() throws FoundationException { + FoundationJNI.INSTANCE.messageInfoEditor_setupDefaults(this.cCtx); + } + + /* + * Unpack serialized message info. + */ + public void unpack(byte[] messageInfoData, byte[] ownerRecipientId, PrivateKey ownerPrivateKey) throws FoundationException { + FoundationJNI.INSTANCE.messageInfoEditor_unpack(this.cCtx, messageInfoData, ownerRecipientId, ownerPrivateKey); + } + + /* + * Add recipient defined with id and public key. + */ + public void addKeyRecipient(byte[] recipientId, PublicKey publicKey) throws FoundationException { + FoundationJNI.INSTANCE.messageInfoEditor_addKeyRecipient(this.cCtx, recipientId, publicKey); + } + + /* + * Remove recipient with a given id. + * Return false if recipient with given id was not found. + */ + public boolean removeKeyRecipient(byte[] recipientId) { + return FoundationJNI.INSTANCE.messageInfoEditor_removeKeyRecipient(this.cCtx, recipientId); + } + + /* + * Remove all existent recipients. + */ + public void removeAll() { + FoundationJNI.INSTANCE.messageInfoEditor_removeAll(this.cCtx); + } + + /* + * Return length of serialized message info. + * Actual length can be obtained right after applying changes. + */ + public int packedLen() { + return FoundationJNI.INSTANCE.messageInfoEditor_packedLen(this.cCtx); + } + + /* + * Return serialized message info. + * Precondition: this method can be called after "apply". + */ + public byte[] pack() { + return FoundationJNI.INSTANCE.messageInfoEditor_pack(this.cCtx); + } +} + diff --git a/wrappers/java/foundation/src/main/java/com/virgilsecurity/crypto/foundation/RecipientCipher.java b/wrappers/java/foundation/src/main/java/com/virgilsecurity/crypto/foundation/RecipientCipher.java index 52136a96a..aea8bd18e 100644 --- a/wrappers/java/foundation/src/main/java/com/virgilsecurity/crypto/foundation/RecipientCipher.java +++ b/wrappers/java/foundation/src/main/java/com/virgilsecurity/crypto/foundation/RecipientCipher.java @@ -102,7 +102,7 @@ public MessageInfoCustomParams customParams() { /* * Return buffer length required to hold message info returned by the - * "start encryption" method. + * "pack message info" method. * Precondition: all recipients and custom parameters should be set. */ public int messageInfoLen() { diff --git a/wrappers/python/virgil_crypto_lib/foundation/__init__.py b/wrappers/python/virgil_crypto_lib/foundation/__init__.py index d7a321388..80e2f829a 100644 --- a/wrappers/python/virgil_crypto_lib/foundation/__init__.py +++ b/wrappers/python/virgil_crypto_lib/foundation/__init__.py @@ -60,6 +60,7 @@ from .group_session_message import GroupSessionMessage from .group_session_ticket import GroupSessionTicket from .group_session import GroupSession +from .message_info_editor import MessageInfoEditor from .cipher import Cipher from .auth_encrypt import AuthEncrypt from .auth_decrypt import AuthDecrypt diff --git a/wrappers/python/virgil_crypto_lib/foundation/_c_bridge/__init__.py b/wrappers/python/virgil_crypto_lib/foundation/_c_bridge/__init__.py index 54aebb86a..f1f29cbbd 100644 --- a/wrappers/python/virgil_crypto_lib/foundation/_c_bridge/__init__.py +++ b/wrappers/python/virgil_crypto_lib/foundation/_c_bridge/__init__.py @@ -79,6 +79,8 @@ from ._vscf_group_session_ticket import VscfGroupSessionTicket from ._vscf_group_session import vscf_group_session_t from ._vscf_group_session import VscfGroupSession +from ._vscf_message_info_editor import vscf_message_info_editor_t +from ._vscf_message_info_editor import VscfMessageInfoEditor from ._vscf_sha224 import vscf_sha224_t from ._vscf_sha224 import VscfSha224 from ._vscf_sha256 import vscf_sha256_t diff --git a/wrappers/python/virgil_crypto_lib/foundation/_c_bridge/_vscf_message_info_editor.py b/wrappers/python/virgil_crypto_lib/foundation/_c_bridge/_vscf_message_info_editor.py new file mode 100644 index 000000000..a7dc2b6e3 --- /dev/null +++ b/wrappers/python/virgil_crypto_lib/foundation/_c_bridge/_vscf_message_info_editor.py @@ -0,0 +1,134 @@ +# Copyright (C) 2015-2019 Virgil Security, Inc. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# (1) Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# (2) Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# (3) Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# Lead Maintainer: Virgil Security Inc. + + +from virgil_crypto_lib._libs import * +from ctypes import * +from ._vscf_impl import vscf_impl_t +from virgil_crypto_lib.common._c_bridge import vsc_data_t +from virgil_crypto_lib.common._c_bridge import vsc_buffer_t + + +class vscf_message_info_editor_t(Structure): + pass + + +class VscfMessageInfoEditor(object): + """Add and/or remove recipients and it's paramteres within message info. + + Usage: + 1. Unpack binary message info that was obtained from RecipientCipher. + 2. Add and/or remove key recipients. + 3. Pack MessagInfo to the binary data.""" + + def __init__(self): + """Create underlying C context.""" + self._ll = LowLevelLibs() + self._lib = self._ll.foundation + + def vscf_message_info_editor_new(self): + vscf_message_info_editor_new = self._lib.vscf_message_info_editor_new + vscf_message_info_editor_new.argtypes = [] + vscf_message_info_editor_new.restype = POINTER(vscf_message_info_editor_t) + return vscf_message_info_editor_new() + + def vscf_message_info_editor_delete(self, ctx): + vscf_message_info_editor_delete = self._lib.vscf_message_info_editor_delete + vscf_message_info_editor_delete.argtypes = [POINTER(vscf_message_info_editor_t)] + vscf_message_info_editor_delete.restype = None + return vscf_message_info_editor_delete(ctx) + + def vscf_message_info_editor_use_random(self, ctx, random): + vscf_message_info_editor_use_random = self._lib.vscf_message_info_editor_use_random + vscf_message_info_editor_use_random.argtypes = [POINTER(vscf_message_info_editor_t), POINTER(vscf_impl_t)] + vscf_message_info_editor_use_random.restype = None + return vscf_message_info_editor_use_random(ctx, random) + + def vscf_message_info_editor_setup_defaults(self, ctx): + """Set depenencies to it's defaults.""" + vscf_message_info_editor_setup_defaults = self._lib.vscf_message_info_editor_setup_defaults + vscf_message_info_editor_setup_defaults.argtypes = [POINTER(vscf_message_info_editor_t)] + vscf_message_info_editor_setup_defaults.restype = c_int + return vscf_message_info_editor_setup_defaults(ctx) + + def vscf_message_info_editor_unpack(self, ctx, message_info_data, owner_recipient_id, owner_private_key): + """Unpack serialized message info.""" + vscf_message_info_editor_unpack = self._lib.vscf_message_info_editor_unpack + vscf_message_info_editor_unpack.argtypes = [POINTER(vscf_message_info_editor_t), vsc_data_t, vsc_data_t, POINTER(vscf_impl_t)] + vscf_message_info_editor_unpack.restype = c_int + return vscf_message_info_editor_unpack(ctx, message_info_data, owner_recipient_id, owner_private_key) + + def vscf_message_info_editor_add_key_recipient(self, ctx, recipient_id, public_key): + """Add recipient defined with id and public key.""" + vscf_message_info_editor_add_key_recipient = self._lib.vscf_message_info_editor_add_key_recipient + vscf_message_info_editor_add_key_recipient.argtypes = [POINTER(vscf_message_info_editor_t), vsc_data_t, POINTER(vscf_impl_t)] + vscf_message_info_editor_add_key_recipient.restype = c_int + return vscf_message_info_editor_add_key_recipient(ctx, recipient_id, public_key) + + def vscf_message_info_editor_remove_key_recipient(self, ctx, recipient_id): + """Remove recipient with a given id. + Return false if recipient with given id was not found.""" + vscf_message_info_editor_remove_key_recipient = self._lib.vscf_message_info_editor_remove_key_recipient + vscf_message_info_editor_remove_key_recipient.argtypes = [POINTER(vscf_message_info_editor_t), vsc_data_t] + vscf_message_info_editor_remove_key_recipient.restype = c_bool + return vscf_message_info_editor_remove_key_recipient(ctx, recipient_id) + + def vscf_message_info_editor_remove_all(self, ctx): + """Remove all existent recipients.""" + vscf_message_info_editor_remove_all = self._lib.vscf_message_info_editor_remove_all + vscf_message_info_editor_remove_all.argtypes = [POINTER(vscf_message_info_editor_t)] + vscf_message_info_editor_remove_all.restype = None + return vscf_message_info_editor_remove_all(ctx) + + def vscf_message_info_editor_packed_len(self, ctx): + """Return length of serialized message info. + Actual length can be obtained right after applying changes.""" + vscf_message_info_editor_packed_len = self._lib.vscf_message_info_editor_packed_len + vscf_message_info_editor_packed_len.argtypes = [POINTER(vscf_message_info_editor_t)] + vscf_message_info_editor_packed_len.restype = c_size_t + return vscf_message_info_editor_packed_len(ctx) + + def vscf_message_info_editor_pack(self, ctx, message_info): + """Return serialized message info. + Precondition: this method can be called after "apply".""" + vscf_message_info_editor_pack = self._lib.vscf_message_info_editor_pack + vscf_message_info_editor_pack.argtypes = [POINTER(vscf_message_info_editor_t), POINTER(vsc_buffer_t)] + vscf_message_info_editor_pack.restype = None + return vscf_message_info_editor_pack(ctx, message_info) + + def vscf_message_info_editor_shallow_copy(self, ctx): + vscf_message_info_editor_shallow_copy = self._lib.vscf_message_info_editor_shallow_copy + vscf_message_info_editor_shallow_copy.argtypes = [POINTER(vscf_message_info_editor_t)] + vscf_message_info_editor_shallow_copy.restype = POINTER(vscf_message_info_editor_t) + return vscf_message_info_editor_shallow_copy(ctx) diff --git a/wrappers/python/virgil_crypto_lib/foundation/_c_bridge/_vscf_recipient_cipher.py b/wrappers/python/virgil_crypto_lib/foundation/_c_bridge/_vscf_recipient_cipher.py index abfc9ea33..052b24039 100644 --- a/wrappers/python/virgil_crypto_lib/foundation/_c_bridge/_vscf_recipient_cipher.py +++ b/wrappers/python/virgil_crypto_lib/foundation/_c_bridge/_vscf_recipient_cipher.py @@ -103,7 +103,7 @@ def vscf_recipient_cipher_custom_params(self, ctx): def vscf_recipient_cipher_message_info_len(self, ctx): """Return buffer length required to hold message info returned by the - "start encryption" method. + "pack message info" method. Precondition: all recipients and custom parameters should be set.""" vscf_recipient_cipher_message_info_len = self._lib.vscf_recipient_cipher_message_info_len vscf_recipient_cipher_message_info_len.argtypes = [POINTER(vscf_recipient_cipher_t)] diff --git a/wrappers/python/virgil_crypto_lib/foundation/message_info_editor.py b/wrappers/python/virgil_crypto_lib/foundation/message_info_editor.py new file mode 100644 index 000000000..39b933c34 --- /dev/null +++ b/wrappers/python/virgil_crypto_lib/foundation/message_info_editor.py @@ -0,0 +1,117 @@ +# Copyright (C) 2015-2019 Virgil Security, Inc. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# (1) Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# (2) Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# (3) Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# Lead Maintainer: Virgil Security Inc. + + +from ctypes import * +from ._c_bridge import VscfMessageInfoEditor +from ._c_bridge import VscfStatus +from virgil_crypto_lib.common._c_bridge import Data +from virgil_crypto_lib.common._c_bridge import Buffer + + +class MessageInfoEditor(object): + """Add and/or remove recipients and it's paramteres within message info. + + Usage: + 1. Unpack binary message info that was obtained from RecipientCipher. + 2. Add and/or remove key recipients. + 3. Pack MessagInfo to the binary data.""" + + def __init__(self): + """Create underlying C context.""" + self._lib_vscf_message_info_editor = VscfMessageInfoEditor() + self.ctx = self._lib_vscf_message_info_editor.vscf_message_info_editor_new() + + def __delete__(self, instance): + """Destroy underlying C context.""" + self._lib_vscf_message_info_editor.vscf_message_info_editor_delete(self.ctx) + + def set_random(self, random): + self._lib_vscf_message_info_editor.vscf_message_info_editor_use_random(self.ctx, random.c_impl) + + def setup_defaults(self): + """Set depenencies to it's defaults.""" + status = self._lib_vscf_message_info_editor.vscf_message_info_editor_setup_defaults(self.ctx) + VscfStatus.handle_status(status) + + def unpack(self, message_info_data, owner_recipient_id, owner_private_key): + """Unpack serialized message info.""" + d_message_info_data = Data(message_info_data) + d_owner_recipient_id = Data(owner_recipient_id) + status = self._lib_vscf_message_info_editor.vscf_message_info_editor_unpack(self.ctx, d_message_info_data.data, d_owner_recipient_id.data, owner_private_key.c_impl) + VscfStatus.handle_status(status) + + def add_key_recipient(self, recipient_id, public_key): + """Add recipient defined with id and public key.""" + d_recipient_id = Data(recipient_id) + status = self._lib_vscf_message_info_editor.vscf_message_info_editor_add_key_recipient(self.ctx, d_recipient_id.data, public_key.c_impl) + VscfStatus.handle_status(status) + + def remove_key_recipient(self, recipient_id): + """Remove recipient with a given id. + Return false if recipient with given id was not found.""" + d_recipient_id = Data(recipient_id) + result = self._lib_vscf_message_info_editor.vscf_message_info_editor_remove_key_recipient(self.ctx, d_recipient_id.data) + return result + + def remove_all(self): + """Remove all existent recipients.""" + self._lib_vscf_message_info_editor.vscf_message_info_editor_remove_all(self.ctx) + + def packed_len(self): + """Return length of serialized message info. + Actual length can be obtained right after applying changes.""" + result = self._lib_vscf_message_info_editor.vscf_message_info_editor_packed_len(self.ctx) + return result + + def pack(self): + """Return serialized message info. + Precondition: this method can be called after "apply".""" + message_info = Buffer(self.packed_len()) + self._lib_vscf_message_info_editor.vscf_message_info_editor_pack(self.ctx, message_info.c_buffer) + return message_info.get_bytes() + + @classmethod + def take_c_ctx(cls, c_ctx): + inst = cls.__new__(cls) + inst._lib_vscf_message_info_editor = VscfMessageInfoEditor() + inst.ctx = c_ctx + return inst + + @classmethod + def use_c_ctx(cls, c_ctx): + inst = cls.__new__(cls) + inst._lib_vscf_message_info_editor = VscfMessageInfoEditor() + inst.ctx = inst._lib_vscf_message_info_editor.vscf_message_info_editor_shallow_copy(c_ctx) + return inst diff --git a/wrappers/python/virgil_crypto_lib/foundation/recipient_cipher.py b/wrappers/python/virgil_crypto_lib/foundation/recipient_cipher.py index 007d18103..25f5178d1 100644 --- a/wrappers/python/virgil_crypto_lib/foundation/recipient_cipher.py +++ b/wrappers/python/virgil_crypto_lib/foundation/recipient_cipher.py @@ -79,7 +79,7 @@ def custom_params(self): def message_info_len(self): """Return buffer length required to hold message info returned by the - "start encryption" method. + "pack message info" method. Precondition: all recipients and custom parameters should be set.""" result = self._lib_vscf_recipient_cipher.vscf_recipient_cipher_message_info_len(self.ctx) return result diff --git a/wrappers/swift/VirgilCrypto/VirgilCryptoFoundation/MessageInfoEditor.swift b/wrappers/swift/VirgilCrypto/VirgilCryptoFoundation/MessageInfoEditor.swift new file mode 100644 index 000000000..7a1763f2c --- /dev/null +++ b/wrappers/swift/VirgilCrypto/VirgilCryptoFoundation/MessageInfoEditor.swift @@ -0,0 +1,152 @@ +/// Copyright (C) 2015-2019 Virgil Security, Inc. +/// +/// All rights reserved. +/// +/// Redistribution and use in source and binary forms, with or without +/// modification, are permitted provided that the following conditions are +/// met: +/// +/// (1) Redistributions of source code must retain the above copyright +/// notice, this list of conditions and the following disclaimer. +/// +/// (2) Redistributions in binary form must reproduce the above copyright +/// notice, this list of conditions and the following disclaimer in +/// the documentation and/or other materials provided with the +/// distribution. +/// +/// (3) Neither the name of the copyright holder nor the names of its +/// contributors may be used to endorse or promote products derived from +/// this software without specific prior written permission. +/// +/// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR +/// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +/// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +/// DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +/// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +/// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +/// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +/// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +/// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +/// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +/// POSSIBILITY OF SUCH DAMAGE. +/// +/// Lead Maintainer: Virgil Security Inc. + + +import Foundation +import VSCFoundation + +/// Add and/or remove recipients and it's paramteres within message info. +/// +/// Usage: +/// 1. Unpack binary message info that was obtained from RecipientCipher. +/// 2. Add and/or remove key recipients. +/// 3. Pack MessagInfo to the binary data. +@objc(VSCFMessageInfoEditor) public class MessageInfoEditor: NSObject { + + /// Handle underlying C context. + @objc public let c_ctx: OpaquePointer + + /// Create underlying C context. + public override init() { + self.c_ctx = vscf_message_info_editor_new() + super.init() + } + + /// Acquire C context. + /// Note. This method is used in generated code only, and SHOULD NOT be used in another way. + public init(take c_ctx: OpaquePointer) { + self.c_ctx = c_ctx + super.init() + } + + /// Acquire retained C context. + /// Note. This method is used in generated code only, and SHOULD NOT be used in another way. + public init(use c_ctx: OpaquePointer) { + self.c_ctx = vscf_message_info_editor_shallow_copy(c_ctx) + super.init() + } + + /// Release underlying C context. + deinit { + vscf_message_info_editor_delete(self.c_ctx) + } + + @objc public func setRandom(random: Random) { + vscf_message_info_editor_release_random(self.c_ctx) + vscf_message_info_editor_use_random(self.c_ctx, random.c_ctx) + } + + /// Set depenencies to it's defaults. + @objc public func setupDefaults() throws { + let proxyResult = vscf_message_info_editor_setup_defaults(self.c_ctx) + + try FoundationError.handleStatus(fromC: proxyResult) + } + + /// Unpack serialized message info. + @objc public func unpack(messageInfoData: Data, ownerRecipientId: Data, ownerPrivateKey: PrivateKey) throws { + let proxyResult = messageInfoData.withUnsafeBytes({ (messageInfoDataPointer: UnsafeRawBufferPointer) -> vscf_status_t in + ownerRecipientId.withUnsafeBytes({ (ownerRecipientIdPointer: UnsafeRawBufferPointer) -> vscf_status_t in + + return vscf_message_info_editor_unpack(self.c_ctx, vsc_data(messageInfoDataPointer.bindMemory(to: byte.self).baseAddress, messageInfoData.count), vsc_data(ownerRecipientIdPointer.bindMemory(to: byte.self).baseAddress, ownerRecipientId.count), ownerPrivateKey.c_ctx) + }) + }) + + try FoundationError.handleStatus(fromC: proxyResult) + } + + /// Add recipient defined with id and public key. + @objc public func addKeyRecipient(recipientId: Data, publicKey: PublicKey) throws { + let proxyResult = recipientId.withUnsafeBytes({ (recipientIdPointer: UnsafeRawBufferPointer) -> vscf_status_t in + + return vscf_message_info_editor_add_key_recipient(self.c_ctx, vsc_data(recipientIdPointer.bindMemory(to: byte.self).baseAddress, recipientId.count), publicKey.c_ctx) + }) + + try FoundationError.handleStatus(fromC: proxyResult) + } + + /// Remove recipient with a given id. + /// Return false if recipient with given id was not found. + @objc public func removeKeyRecipient(recipientId: Data) -> Bool { + let proxyResult = recipientId.withUnsafeBytes({ (recipientIdPointer: UnsafeRawBufferPointer) -> Bool in + + return vscf_message_info_editor_remove_key_recipient(self.c_ctx, vsc_data(recipientIdPointer.bindMemory(to: byte.self).baseAddress, recipientId.count)) + }) + + return proxyResult + } + + /// Remove all existent recipients. + @objc public func removeAll() { + vscf_message_info_editor_remove_all(self.c_ctx) + } + + /// Return length of serialized message info. + /// Actual length can be obtained right after applying changes. + @objc public func packedLen() -> Int { + let proxyResult = vscf_message_info_editor_packed_len(self.c_ctx) + + return proxyResult + } + + /// Return serialized message info. + /// Precondition: this method can be called after "apply". + @objc public func pack() -> Data { + let messageInfoCount = self.packedLen() + var messageInfo = Data(count: messageInfoCount) + var messageInfoBuf = vsc_buffer_new() + defer { + vsc_buffer_delete(messageInfoBuf) + } + + messageInfo.withUnsafeMutableBytes({ (messageInfoPointer: UnsafeMutableRawBufferPointer) -> Void in + vsc_buffer_use(messageInfoBuf, messageInfoPointer.bindMemory(to: byte.self).baseAddress, messageInfoCount) + + vscf_message_info_editor_pack(self.c_ctx, messageInfoBuf) + }) + messageInfo.count = vsc_buffer_len(messageInfoBuf) + + return messageInfo + } +} diff --git a/wrappers/swift/VirgilCrypto/VirgilCryptoFoundation/RecipientCipher.swift b/wrappers/swift/VirgilCrypto/VirgilCryptoFoundation/RecipientCipher.swift index fdabe648f..4d57a35a0 100644 --- a/wrappers/swift/VirgilCrypto/VirgilCryptoFoundation/RecipientCipher.swift +++ b/wrappers/swift/VirgilCrypto/VirgilCryptoFoundation/RecipientCipher.swift @@ -101,7 +101,7 @@ import VSCFoundation } /// Return buffer length required to hold message info returned by the - /// "start encryption" method. + /// "pack message info" method. /// Precondition: all recipients and custom parameters should be set. @objc public func messageInfoLen() -> Int { let proxyResult = vscf_recipient_cipher_message_info_len(self.c_ctx) diff --git a/wrappers/wasm/foundation/exported_functions.json b/wrappers/wasm/foundation/exported_functions.json index b90f88d21..fdc1c4d5a 100644 --- a/wrappers/wasm/foundation/exported_functions.json +++ b/wrappers/wasm/foundation/exported_functions.json @@ -223,6 +223,18 @@ "_vscf_group_session_decrypt_len", "_vscf_group_session_decrypt", "_vscf_group_session_create_group_ticket", + "_vscf_message_info_editor_new", + "_vscf_message_info_editor_shallow_copy", + "_vscf_message_info_editor_delete", + "_vscf_message_info_editor_release_random", + "_vscf_message_info_editor_use_random", + "_vscf_message_info_editor_setup_defaults", + "_vscf_message_info_editor_unpack", + "_vscf_message_info_editor_add_key_recipient", + "_vscf_message_info_editor_remove_key_recipient", + "_vscf_message_info_editor_remove_all", + "_vscf_message_info_editor_packed_len", + "_vscf_message_info_editor_pack", "_vscf_sha224_new", "_vscf_sha224_shallow_copy", "_vscf_sha224_delete", diff --git a/wrappers/wasm/foundation/src/MessageInfoEditor.js b/wrappers/wasm/foundation/src/MessageInfoEditor.js new file mode 100644 index 000000000..3b5d9861a --- /dev/null +++ b/wrappers/wasm/foundation/src/MessageInfoEditor.js @@ -0,0 +1,264 @@ +/** + * Copyright (C) 2015-2019 Virgil Security, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * (1) Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * (2) Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * (3) Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Lead Maintainer: Virgil Security Inc. + */ + + +const precondition = require('./precondition'); + +const initMessageInfoEditor = (Module, modules) => { + /** + * Add and/or remove recipients and it's paramteres within message info. + * + * Usage: + * 1. Unpack binary message info that was obtained from RecipientCipher. + * 2. Add and/or remove key recipients. + * 3. Pack MessagInfo to the binary data. + */ + class MessageInfoEditor { + + /** + * Create object with underlying C context. + * + * Note. Parameter 'ctxPtr' SHOULD be passed from the generated code only. + */ + constructor(ctxPtr) { + this.name = 'MessageInfoEditor'; + + if (typeof ctxPtr === 'undefined') { + this.ctxPtr = Module._vscf_message_info_editor_new(); + } else { + this.ctxPtr = ctxPtr; + } + } + + /** + * Acquire C context by making it's shallow copy. + * + * Note. This method is used in generated code only, and SHOULD NOT be used in another way. + */ + static newAndUseCContext(ctxPtr) { + // assert(typeof ctxPtr === 'number'); + return new MessageInfoEditor(Module._vscf_message_info_editor_shallow_copy(ctxPtr)); + } + + /** + * Acquire C context by taking it ownership. + * + * Note. This method is used in generated code only, and SHOULD NOT be used in another way. + */ + static newAndTakeCContext(ctxPtr) { + // assert(typeof ctxPtr === 'number'); + return new MessageInfoEditor(ctxPtr); + } + + /** + * Release underlying C context. + */ + delete() { + if (typeof this.ctxPtr !== 'undefined' && this.ctxPtr !== null) { + Module._vscf_message_info_editor_delete(this.ctxPtr); + this.ctxPtr = null; + } + } + + set random(random) { + precondition.ensureNotNull('this.ctxPtr', this.ctxPtr); + precondition.ensureImplementInterface('random', random, 'Foundation.Random', modules.FoundationInterfaceTag.RANDOM, modules.FoundationInterface); + Module._vscf_message_info_editor_release_random(this.ctxPtr) + Module._vscf_message_info_editor_use_random(this.ctxPtr, random.ctxPtr) + } + + /** + * Set depenencies to it's defaults. + */ + setupDefaults() { + precondition.ensureNotNull('this.ctxPtr', this.ctxPtr); + const proxyResult = Module._vscf_message_info_editor_setup_defaults(this.ctxPtr); + modules.FoundationError.handleStatusCode(proxyResult); + } + + /** + * Unpack serialized message info. + */ + unpack(messageInfoData, ownerRecipientId, ownerPrivateKey) { + precondition.ensureNotNull('this.ctxPtr', this.ctxPtr); + precondition.ensureByteArray('messageInfoData', messageInfoData); + precondition.ensureByteArray('ownerRecipientId', ownerRecipientId); + precondition.ensureImplementInterface('ownerPrivateKey', ownerPrivateKey, 'Foundation.PrivateKey', modules.FoundationInterfaceTag.PRIVATE_KEY, modules.FoundationInterface); + + // Copy bytes from JS memory to the WASM memory. + const messageInfoDataSize = messageInfoData.length * messageInfoData.BYTES_PER_ELEMENT; + const messageInfoDataPtr = Module._malloc(messageInfoDataSize); + Module.HEAP8.set(messageInfoData, messageInfoDataPtr); + + // Create C structure vsc_data_t. + const messageInfoDataCtxSize = Module._vsc_data_ctx_size(); + const messageInfoDataCtxPtr = Module._malloc(messageInfoDataCtxSize); + + // Point created vsc_data_t object to the copied bytes. + Module._vsc_data(messageInfoDataCtxPtr, messageInfoDataPtr, messageInfoDataSize); + + // Copy bytes from JS memory to the WASM memory. + const ownerRecipientIdSize = ownerRecipientId.length * ownerRecipientId.BYTES_PER_ELEMENT; + const ownerRecipientIdPtr = Module._malloc(ownerRecipientIdSize); + Module.HEAP8.set(ownerRecipientId, ownerRecipientIdPtr); + + // Create C structure vsc_data_t. + const ownerRecipientIdCtxSize = Module._vsc_data_ctx_size(); + const ownerRecipientIdCtxPtr = Module._malloc(ownerRecipientIdCtxSize); + + // Point created vsc_data_t object to the copied bytes. + Module._vsc_data(ownerRecipientIdCtxPtr, ownerRecipientIdPtr, ownerRecipientIdSize); + + try { + const proxyResult = Module._vscf_message_info_editor_unpack(this.ctxPtr, messageInfoDataCtxPtr, ownerRecipientIdCtxPtr, ownerPrivateKey.ctxPtr); + modules.FoundationError.handleStatusCode(proxyResult); + } finally { + Module._free(messageInfoDataPtr); + Module._free(messageInfoDataCtxPtr); + Module._free(ownerRecipientIdPtr); + Module._free(ownerRecipientIdCtxPtr); + } + } + + /** + * Add recipient defined with id and public key. + */ + addKeyRecipient(recipientId, publicKey) { + precondition.ensureNotNull('this.ctxPtr', this.ctxPtr); + precondition.ensureByteArray('recipientId', recipientId); + precondition.ensureImplementInterface('publicKey', publicKey, 'Foundation.PublicKey', modules.FoundationInterfaceTag.PUBLIC_KEY, modules.FoundationInterface); + + // Copy bytes from JS memory to the WASM memory. + const recipientIdSize = recipientId.length * recipientId.BYTES_PER_ELEMENT; + const recipientIdPtr = Module._malloc(recipientIdSize); + Module.HEAP8.set(recipientId, recipientIdPtr); + + // Create C structure vsc_data_t. + const recipientIdCtxSize = Module._vsc_data_ctx_size(); + const recipientIdCtxPtr = Module._malloc(recipientIdCtxSize); + + // Point created vsc_data_t object to the copied bytes. + Module._vsc_data(recipientIdCtxPtr, recipientIdPtr, recipientIdSize); + + try { + const proxyResult = Module._vscf_message_info_editor_add_key_recipient(this.ctxPtr, recipientIdCtxPtr, publicKey.ctxPtr); + modules.FoundationError.handleStatusCode(proxyResult); + } finally { + Module._free(recipientIdPtr); + Module._free(recipientIdCtxPtr); + } + } + + /** + * Remove recipient with a given id. + * Return false if recipient with given id was not found. + */ + removeKeyRecipient(recipientId) { + precondition.ensureNotNull('this.ctxPtr', this.ctxPtr); + precondition.ensureByteArray('recipientId', recipientId); + + // Copy bytes from JS memory to the WASM memory. + const recipientIdSize = recipientId.length * recipientId.BYTES_PER_ELEMENT; + const recipientIdPtr = Module._malloc(recipientIdSize); + Module.HEAP8.set(recipientId, recipientIdPtr); + + // Create C structure vsc_data_t. + const recipientIdCtxSize = Module._vsc_data_ctx_size(); + const recipientIdCtxPtr = Module._malloc(recipientIdCtxSize); + + // Point created vsc_data_t object to the copied bytes. + Module._vsc_data(recipientIdCtxPtr, recipientIdPtr, recipientIdSize); + + let proxyResult; + + try { + proxyResult = Module._vscf_message_info_editor_remove_key_recipient(this.ctxPtr, recipientIdCtxPtr); + + const booleanResult = !!proxyResult; + return booleanResult; + } finally { + Module._free(recipientIdPtr); + Module._free(recipientIdCtxPtr); + } + } + + /** + * Remove all existent recipients. + */ + removeAll() { + precondition.ensureNotNull('this.ctxPtr', this.ctxPtr); + Module._vscf_message_info_editor_remove_all(this.ctxPtr); + } + + /** + * Return length of serialized message info. + * Actual length can be obtained right after applying changes. + */ + packedLen() { + precondition.ensureNotNull('this.ctxPtr', this.ctxPtr); + + let proxyResult; + proxyResult = Module._vscf_message_info_editor_packed_len(this.ctxPtr); + return proxyResult; + } + + /** + * Return serialized message info. + * Precondition: this method can be called after "apply". + */ + pack() { + precondition.ensureNotNull('this.ctxPtr', this.ctxPtr); + + const messageInfoCapacity = this.packedLen(); + const messageInfoCtxPtr = Module._vsc_buffer_new_with_capacity(messageInfoCapacity); + + try { + Module._vscf_message_info_editor_pack(this.ctxPtr, messageInfoCtxPtr); + + const messageInfoPtr = Module._vsc_buffer_bytes(messageInfoCtxPtr); + const messageInfoPtrLen = Module._vsc_buffer_len(messageInfoCtxPtr); + const messageInfo = Module.HEAPU8.slice(messageInfoPtr, messageInfoPtr + messageInfoPtrLen); + return messageInfo; + } finally { + Module._vsc_buffer_delete(messageInfoCtxPtr); + } + } + } + + return MessageInfoEditor; +}; + +module.exports = initMessageInfoEditor; diff --git a/wrappers/wasm/foundation/src/RecipientCipher.js b/wrappers/wasm/foundation/src/RecipientCipher.js index 38e031e35..8069480dc 100644 --- a/wrappers/wasm/foundation/src/RecipientCipher.js +++ b/wrappers/wasm/foundation/src/RecipientCipher.js @@ -156,7 +156,7 @@ const initRecipientCipher = (Module, modules) => { /** * Return buffer length required to hold message info returned by the - * "start encryption" method. + * "pack message info" method. * Precondition: all recipients and custom parameters should be set. */ messageInfoLen() { diff --git a/wrappers/wasm/foundation/src/asmjs.js b/wrappers/wasm/foundation/src/asmjs.js index f1393defb..b44d1e861 100644 --- a/wrappers/wasm/foundation/src/asmjs.js +++ b/wrappers/wasm/foundation/src/asmjs.js @@ -66,6 +66,7 @@ const initBrainkeyServer = require('./BrainkeyServer'); const initGroupSessionMessage = require('./GroupSessionMessage'); const initGroupSessionTicket = require('./GroupSessionTicket'); const initGroupSession = require('./GroupSession'); +const initMessageInfoEditor = require('./MessageInfoEditor'); const initSha224 = require('./Sha224'); const initSha256 = require('./Sha256'); const initSha384 = require('./Sha384'); @@ -142,6 +143,7 @@ const initProject = () => { modules.GroupSessionMessage = initGroupSessionMessage(foundationModule, modules); modules.GroupSessionTicket = initGroupSessionTicket(foundationModule, modules); modules.GroupSession = initGroupSession(foundationModule, modules); + modules.MessageInfoEditor = initMessageInfoEditor(foundationModule, modules); modules.Sha224 = initSha224(foundationModule, modules); modules.Sha256 = initSha256(foundationModule, modules); modules.Sha384 = initSha384(foundationModule, modules); diff --git a/wrappers/wasm/foundation/src/index.js b/wrappers/wasm/foundation/src/index.js index 5ed76d33a..bee0b41e8 100644 --- a/wrappers/wasm/foundation/src/index.js +++ b/wrappers/wasm/foundation/src/index.js @@ -66,6 +66,7 @@ const initBrainkeyServer = require('./BrainkeyServer'); const initGroupSessionMessage = require('./GroupSessionMessage'); const initGroupSessionTicket = require('./GroupSessionTicket'); const initGroupSession = require('./GroupSession'); +const initMessageInfoEditor = require('./MessageInfoEditor'); const initSha224 = require('./Sha224'); const initSha256 = require('./Sha256'); const initSha384 = require('./Sha384'); @@ -144,6 +145,7 @@ const initProject = () => { modules.GroupSessionMessage = initGroupSessionMessage(foundationModule, modules); modules.GroupSessionTicket = initGroupSessionTicket(foundationModule, modules); modules.GroupSession = initGroupSession(foundationModule, modules); + modules.MessageInfoEditor = initMessageInfoEditor(foundationModule, modules); modules.Sha224 = initSha224(foundationModule, modules); modules.Sha256 = initSha256(foundationModule, modules); modules.Sha384 = initSha384(foundationModule, modules); From ba276fb584ecfd04b4963bdb3e974e2d50af4f08 Mon Sep 17 00:00:00 2001 From: SergeySeroshtan Date: Fri, 6 Sep 2019 21:54:54 +0300 Subject: [PATCH 5/9] Fix memory leaks (lib, foundation) Introduced by commit "Implement support for managing recipients within MessageInfo" --- library/foundation/src/vscf_message_info_editor.c | 1 + 1 file changed, 1 insertion(+) diff --git a/library/foundation/src/vscf_message_info_editor.c b/library/foundation/src/vscf_message_info_editor.c index 7e81f403a..5721aeb58 100644 --- a/library/foundation/src/vscf_message_info_editor.c +++ b/library/foundation/src/vscf_message_info_editor.c @@ -311,6 +311,7 @@ vscf_message_info_editor_cleanup_ctx(vscf_message_info_editor_t *self) { VSCF_ASSERT_PTR(self); vscf_impl_destroy(&self->message_info_serializer); + vscf_message_info_destroy(&self->message_info); vsc_buffer_destroy(&self->encryption_key); } From 39533eaa9ed1798e94671ae4d03ed51870bd5142 Mon Sep 17 00:00:00 2001 From: SergeySeroshtan Date: Fri, 6 Sep 2019 22:36:58 +0300 Subject: [PATCH 6/9] Fix memory leaks (lib, foundation) Introduced by commit "Implement support for managing recipients within MessageInfo" --- library/foundation/src/vscf_key_recipient_info_list.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/library/foundation/src/vscf_key_recipient_info_list.c b/library/foundation/src/vscf_key_recipient_info_list.c index 5b97e76d9..bb9617bcb 100644 --- a/library/foundation/src/vscf_key_recipient_info_list.c +++ b/library/foundation/src/vscf_key_recipient_info_list.c @@ -280,8 +280,13 @@ vscf_key_recipient_info_list_remove_self(vscf_key_recipient_info_list_t *self) { vscf_key_recipient_info_destroy(&self->item); if (self->next) { - self->item = self->next->item; - self->next = self->next->next; + vscf_key_recipient_info_list_t *next = self->next; + self->item = next->item; + self->next = next->next; + next->next = NULL; // prevent chain destruction + next->item = NULL; + next->prev = NULL; + vscf_key_recipient_info_list_destroy(&next); } } From 19f02293b9e85534b7c20204555e4282e06a76fd Mon Sep 17 00:00:00 2001 From: SergeySeroshtan Date: Mon, 9 Sep 2019 06:58:44 +0300 Subject: [PATCH 7/9] Run in parallel android testing and building python packages (jenkins-ci) --- Jenkinsfile | 501 ++++++++++++++++++++++++++-------------------------- 1 file changed, 252 insertions(+), 249 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 8e8d3cdfe..5d8a072ee 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -605,297 +605,300 @@ def build_LangPython_Windows(slave) { }} } - // -------------------------------------------------------------------------- -// Python packaging +// Packaging & Testing // -------------------------------------------------------------------------- -node("build-docker") { - stage('Build Python packages') { - // Clean workspace - docker.image('python:2.7').inside("--user root"){ - clearContentUnix() - } - - // Linux - unstash 'python_wrapper_linux' - - dir('wrappers/python') { - docker.image("python:2.7").inside("--user root"){ - sh "pip install wheel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name manylinux1_x86_64" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name manylinux1_x86_64" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name manylinux1_i686" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name manylinux1_i686" +def buildPythonPackages() { + return { node("build-docker") { + stage('Build Python packages') { + // Clean workspace + docker.image('python:2.7').inside("--user root") { + clearContentUnix() } - docker.image("python:3.4").inside("--user root"){ - sh "pip install wheel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name manylinux1_x86_64" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name manylinux1_x86_64" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name manylinux1_i686" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name manylinux1_i686" - } + // Linux + unstash 'python_wrapper_linux' + + dir('wrappers/python') { + docker.image("python:2.7").inside("--user root") { + sh "pip install wheel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name manylinux1_x86_64" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name manylinux1_x86_64" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name manylinux1_i686" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name manylinux1_i686" + } - docker.image("python:3.5").inside("--user root"){ - sh "pip install wheel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name manylinux1_x86_64" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name manylinux1_x86_64" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name manylinux1_i686" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name manylinux1_i686" - } + docker.image("python:3.4").inside("--user root") { + sh "pip install wheel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name manylinux1_x86_64" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name manylinux1_x86_64" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name manylinux1_i686" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name manylinux1_i686" + } + + docker.image("python:3.5").inside("--user root") { + sh "pip install wheel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name manylinux1_x86_64" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name manylinux1_x86_64" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name manylinux1_i686" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name manylinux1_i686" + } - docker.image("python:3.6").inside("--user root"){ - sh "pip install wheel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name manylinux1_x86_64" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name manylinux1_x86_64" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name manylinux1_i686" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name manylinux1_i686" + docker.image("python:3.6").inside("--user root") { + sh "pip install wheel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name manylinux1_x86_64" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name manylinux1_x86_64" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name manylinux1_i686" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name manylinux1_i686" + } + + docker.image("python:3.7").inside("--user root") { + sh "pip install wheel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name manylinux1_x86_64" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name manylinux1_x86_64" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name manylinux1_i686" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name manylinux1_i686" + } } - docker.image("python:3.7").inside("--user root"){ - sh "pip install wheel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name manylinux1_x86_64" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name manylinux1_x86_64" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name manylinux1_i686" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name manylinux1_i686" + stash includes: 'wrappers/python/dist/**', name: 'python_linux' + + // Clean workspace + docker.image('python:2.7').inside("--user root") { + clearContentUnix() } - } - stash includes: 'wrappers/python/dist/**', name: 'python_linux' + // MacOs + unstash 'python_wrapper_macos' - // Clean workspace - docker.image('python:2.7').inside("--user root"){ - clearContentUnix() - } + dir('wrappers/python') { + docker.image("python:2.7").inside("--user root") { + sh "pip install wheel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name macosx_10_12_intel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name macosx_10_12_intel" + } - // MacOs - unstash 'python_wrapper_macos' + docker.image("python:3.4").inside("--user root") { + sh "pip install wheel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name macosx_10_12_intel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name macosx_10_12_intel" + } - dir('wrappers/python') { - docker.image("python:2.7").inside("--user root"){ - sh "pip install wheel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name macosx_10_12_intel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name macosx_10_12_intel" - } + docker.image("python:3.5").inside("--user root") { + sh "pip install wheel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name macosx_10_12_intel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name macosx_10_12_intel" + } - docker.image("python:3.4").inside("--user root"){ - sh "pip install wheel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name macosx_10_12_intel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name macosx_10_12_intel" - } + docker.image("python:3.6").inside("--user root") { + sh "pip install wheel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name macosx_10_12_intel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name macosx_10_12_intel" + } - docker.image("python:3.5").inside("--user root"){ - sh "pip install wheel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name macosx_10_12_intel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name macosx_10_12_intel" + docker.image("python:3.7").inside("--user root") { + sh "pip install wheel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name macosx_10_12_intel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name macosx_10_12_intel" + } } - docker.image("python:3.6").inside("--user root"){ - sh "pip install wheel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name macosx_10_12_intel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name macosx_10_12_intel" + //Fixing Python ABI tag + docker.image("python:2.7").inside("--user root") { + sh 'for file in wrappers/python/dist/*-cp27mu-*.whl; do echo $file | mv $file $(sed -r \'s/cp27mu/cp27m/g\'); done' } + stash includes: 'wrappers/python/dist/**', name: 'python_macos' - docker.image("python:3.7").inside("--user root"){ - sh "pip install wheel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name macosx_10_12_intel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name macosx_10_12_intel" + // Clean workspace + docker.image('python:2.7').inside("--user root") { + clearContentUnix() } - } - //Fixing Python ABI tag - docker.image("python:2.7").inside("--user root"){ - sh 'for file in wrappers/python/dist/*-cp27mu-*.whl; do echo $file | mv $file $(sed -r \'s/cp27mu/cp27m/g\'); done' - } - stash includes: 'wrappers/python/dist/**', name: 'python_macos' + // Windows x86 + unstash 'python_wrapper_windows_x86' + sh "rm -rf wrappers/python/virgil_crypto_lib/pythia" - // Clean workspace - docker.image('python:2.7').inside("--user root"){ - clearContentUnix() - } + dir('wrappers/python') { + docker.image("python:2.7").inside("--user root") { + sh "pip install wheel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name win32" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name win32" + } - // Windows x86 - unstash 'python_wrapper_windows_x86' - sh "rm -rf wrappers/python/virgil_crypto_lib/pythia" - - dir('wrappers/python') { - docker.image("python:2.7").inside("--user root"){ - sh "pip install wheel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name win32" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name win32" - } + docker.image("python:3.4").inside("--user root") { + sh "pip install wheel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name win32" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name win32" + } - docker.image("python:3.4").inside("--user root"){ - sh "pip install wheel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name win32" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name win32" - } + docker.image("python:3.5").inside("--user root") { + sh "pip install wheel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name win32" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name win32" + } - docker.image("python:3.5").inside("--user root"){ - sh "pip install wheel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name win32" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name win32" - } + docker.image("python:3.6").inside("--user root") { + sh "pip install wheel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name win32" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name win32" + } - docker.image("python:3.6").inside("--user root"){ - sh "pip install wheel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name win32" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name win32" + docker.image("python:3.7").inside("--user root") { + sh "pip install wheel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name win32" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name win32" + } } - docker.image("python:3.7").inside("--user root"){ - sh "pip install wheel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name win32" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name win32" - } - } + // Windows x86_64 + unstash 'python_wrapper_windows_x86_64' + sh "rm -rf wrappers/python/virgil_crypto_lib/pythia" - // Windows x86_64 - unstash 'python_wrapper_windows_x86_64' - sh "rm -rf wrappers/python/virgil_crypto_lib/pythia" - - dir('wrappers/python') { - docker.image("python:2.7").inside("--user root"){ - sh "pip install wheel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name win_amd64" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name win_amd64" - } + dir('wrappers/python') { + docker.image("python:2.7").inside("--user root") { + sh "pip install wheel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name win_amd64" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name win_amd64" + } - docker.image("python:3.4").inside("--user root"){ - sh "pip install wheel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name win_amd64" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name win_amd64" - } + docker.image("python:3.4").inside("--user root") { + sh "pip install wheel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name win_amd64" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name win_amd64" + } - docker.image("python:3.5").inside("--user root"){ - sh "pip install wheel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name win_amd64" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name win_amd64" - } + docker.image("python:3.5").inside("--user root") { + sh "pip install wheel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name win_amd64" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name win_amd64" + } - docker.image("python:3.6").inside("--user root"){ - sh "pip install wheel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name win_amd64" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name win_amd64" - } + docker.image("python:3.6").inside("--user root") { + sh "pip install wheel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name win_amd64" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name win_amd64" + } - docker.image("python:3.7").inside("--user root"){ - sh "pip install wheel" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_egg --plat-name win_amd64" - cleanPythonBuildDirectoriesLinux() - sh "python setup.py bdist_wheel --plat-name win_amd64" + docker.image("python:3.7").inside("--user root") { + sh "pip install wheel" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_egg --plat-name win_amd64" + cleanPythonBuildDirectoriesLinux() + sh "python setup.py bdist_wheel --plat-name win_amd64" + } } - } - //Fixing Python ABI tag - docker.image("python:2.7").inside("--user root"){ - sh 'for file in wrappers/python/dist/*-cp27mu-*.whl; do echo $file | mv $file $(sed -r \'s/cp27mu/cp27m/g\'); done' + //Fixing Python ABI tag + docker.image("python:2.7").inside("--user root") { + sh 'for file in wrappers/python/dist/*-cp27mu-*.whl; do echo $file | mv $file $(sed -r \'s/cp27mu/cp27m/g\'); done' + } + stash includes: 'wrappers/python/dist/**', name: 'python_windows' } - stash includes: 'wrappers/python/dist/**', name: 'python_windows' - } + }} } +def testAndroidArtifacts() { + return { node('build-os-x') { + stage('Test Android artifacts') { + echo "RUN_ANDROID_TESTS = ${params.RUN_ANDROID_TESTS}" + echo "DEPLOY_ANDROID_ARTIFACTS = ${params.DEPLOY_ANDROID_ARTIFACTS}" + if (!params.RUN_ANDROID_TESTS && !params.DEPLOY_ANDROID_ARTIFACTS) { + echo "Skipped due to the false parameter: RUN_ANDROID_TESTS" + return + } + clearContentUnix() + unstash "src" + unstash "java_android_x86" + unstash "java_android_x86_64" + unstash "java_android_armeabi_v7a" + unstash "java_android_arm64_v8a" -// -------------------------------------------------------------------------- -// Android tests -// -------------------------------------------------------------------------- -node('build-os-x') { - stage('Test Android artifacts') { - echo "RUN_ANDROID_TESTS = ${params.RUN_ANDROID_TESTS}" - echo "DEPLOY_ANDROID_ARTIFACTS = ${params.DEPLOY_ANDROID_ARTIFACTS}" - if (!params.RUN_ANDROID_TESTS && !params.DEPLOY_ANDROID_ARTIFACTS) { - echo "Skipped due to the false parameter: RUN_ANDROID_TESTS" - return - } - clearContentUnix() - unstash "src" - unstash "java_android_x86" - unstash "java_android_x86_64" - unstash "java_android_armeabi_v7a" - unstash "java_android_arm64_v8a" - - withEnv(['ANDROID_HOME=/Users/virgil/Library/VirgilEnviroment/android-sdk']) { - sh ''' - export PATH=$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools:$PATH - adb devices | grep emulator | cut -f1 | while read line; do adb -s $line emu kill; done - ''' - sh ''' - export PATH=$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools:$PATH - emulator -avd test_x86_64 -netdelay none -netspeed full -no-window -no-audio -gpu off & - android-wait-for-emulator.sh - cd wrappers/java/android - ./gradlew clean connectedAndroidTest - adb devices | grep emulator | cut -f1 | while read line; do adb -s $line emu kill; done - ''' - sh ''' - export PATH=$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools:$PATH - emulator -avd test_x86 -netdelay none -netspeed full -no-window -no-audio -gpu off & - android-wait-for-emulator.sh - cd wrappers/java/android - ./gradlew clean connectedAndroidTest - adb devices | grep emulator | cut -f1 | while read line; do adb -s $line emu kill; done - ''' - sh ''' - export PATH=$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools:$PATH - emulator -avd test_v7a -netdelay none -netspeed full -no-window -no-audio -gpu off & - android-wait-for-emulator.sh - cd wrappers/java/android - ./gradlew clean connectedAndroidTest - adb devices | grep emulator | cut -f1 | while read line; do adb -s $line emu kill; done - ''' + withEnv(['ANDROID_HOME=/Users/virgil/Library/VirgilEnviroment/android-sdk']) { + sh ''' + export PATH=$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools:$PATH + adb devices | grep emulator | cut -f1 | while read line; do adb -s $line emu kill; done + ''' + sh ''' + export PATH=$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools:$PATH + emulator -avd test_x86_64 -netdelay none -netspeed full -no-window -no-audio -gpu off & + android-wait-for-emulator.sh + cd wrappers/java/android + ./gradlew clean connectedAndroidTest + adb devices | grep emulator | cut -f1 | while read line; do adb -s $line emu kill; done + ''' + sh ''' + export PATH=$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools:$PATH + emulator -avd test_x86 -netdelay none -netspeed full -no-window -no-audio -gpu off & + android-wait-for-emulator.sh + cd wrappers/java/android + ./gradlew clean connectedAndroidTest + adb devices | grep emulator | cut -f1 | while read line; do adb -s $line emu kill; done + ''' + sh ''' + export PATH=$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools:$PATH + emulator -avd test_v7a -netdelay none -netspeed full -no-window -no-audio -gpu off & + android-wait-for-emulator.sh + cd wrappers/java/android + ./gradlew clean connectedAndroidTest + adb devices | grep emulator | cut -f1 | while read line; do adb -s $line emu kill; done + ''' + } } - } + }} } +def packaging_and_testing_nodes = [:] +packaging_and_testing_nodes['build-python-packages'] = buildPythonPackages() +packaging_and_testing_nodes['test-android-artifacts'] = testAndroidArtifacts() +parallel(packaging_and_testing_nodes) // -------------------------------------------------------------------------- // Deploy From 17dcdb4131e633d8dc122e0fc6e0744ca8cb8c3e Mon Sep 17 00:00:00 2001 From: SergeySeroshtan Date: Mon, 9 Sep 2019 07:33:44 +0300 Subject: [PATCH 8/9] Bump version to the v0.10.2 --- CMakeLists.txt | 2 +- VERSION | 2 +- codegen/main.xml | 2 +- wrappers/java/android/build.gradle | 2 +- wrappers/java/benchmark/pom.xml | 2 +- wrappers/java/common/pom.xml | 2 +- wrappers/java/foundation/pom.xml | 2 +- wrappers/java/phe/pom.xml | 2 +- wrappers/java/pom.xml | 2 +- wrappers/java/pythia/pom.xml | 2 +- wrappers/java/ratchet/pom.xml | 2 +- wrappers/python/setup.py | 2 +- wrappers/python/virgil_crypto_lib/__init__.py | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 83dbf3f61..e88cbea31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,7 +57,7 @@ include("cmake/protobuf.cmake") # --------------------------------------------------------------------------- # Version options # --------------------------------------------------------------------------- -set(VIRGIL_CRYPTO_VERSION_LABEL "dev1" CACHE STRING "Version label, i.e. beta, rc1.") +set(VIRGIL_CRYPTO_VERSION_LABEL "" CACHE STRING "Version label, i.e. beta, rc1.") # --------------------------------------------------------------------------- # Build options diff --git a/VERSION b/VERSION index 95e4a375a..5eef0f10e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.10.2-dev1 +0.10.2 diff --git a/codegen/main.xml b/codegen/main.xml index 53264ff95..5008748e6 100644 --- a/codegen/main.xml +++ b/codegen/main.xml @@ -40,7 +40,7 @@ - + diff --git a/wrappers/java/android/build.gradle b/wrappers/java/android/build.gradle index 77cfdd7a8..f7da71d6d 100644 --- a/wrappers/java/android/build.gradle +++ b/wrappers/java/android/build.gradle @@ -21,7 +21,7 @@ allprojects { mavenLocal() } group "com.virgilsecurity.crypto" - version "0.10.2-SNAPSHOT" + version "0.10.2" def authentication_username = hasProperty('authentication_username') ? authentication_username : System.getenv('authentication_username') def authentication_password = hasProperty('authentication_password') ? authentication_password : System.getenv('authentication_password') diff --git a/wrappers/java/benchmark/pom.xml b/wrappers/java/benchmark/pom.xml index 53bc22079..757b03477 100644 --- a/wrappers/java/benchmark/pom.xml +++ b/wrappers/java/benchmark/pom.xml @@ -5,7 +5,7 @@ com.virgilsecurity.crypto parent - 0.10.2-SNAPSHOT + 0.10.2 benchmark diff --git a/wrappers/java/common/pom.xml b/wrappers/java/common/pom.xml index 559e4210e..f3a87927b 100755 --- a/wrappers/java/common/pom.xml +++ b/wrappers/java/common/pom.xml @@ -36,7 +36,7 @@ com.virgilsecurity.crypto parent - 0.10.2-SNAPSHOT + 0.10.2 jar common diff --git a/wrappers/java/foundation/pom.xml b/wrappers/java/foundation/pom.xml index 286f76063..b1a1917f0 100755 --- a/wrappers/java/foundation/pom.xml +++ b/wrappers/java/foundation/pom.xml @@ -36,7 +36,7 @@ com.virgilsecurity.crypto parent - 0.10.2-SNAPSHOT + 0.10.2 foundation diff --git a/wrappers/java/phe/pom.xml b/wrappers/java/phe/pom.xml index c5ba71d5d..c8721282b 100755 --- a/wrappers/java/phe/pom.xml +++ b/wrappers/java/phe/pom.xml @@ -36,7 +36,7 @@ com.virgilsecurity.crypto parent - 0.10.2-SNAPSHOT + 0.10.2 phe diff --git a/wrappers/java/pom.xml b/wrappers/java/pom.xml index a8a606625..0d14eec86 100755 --- a/wrappers/java/pom.xml +++ b/wrappers/java/pom.xml @@ -36,7 +36,7 @@ com.virgilsecurity.crypto parent pom - 0.10.2-SNAPSHOT + 0.10.2 Virgil Security Crypto Library diff --git a/wrappers/java/pythia/pom.xml b/wrappers/java/pythia/pom.xml index 3f212053c..561392205 100755 --- a/wrappers/java/pythia/pom.xml +++ b/wrappers/java/pythia/pom.xml @@ -36,7 +36,7 @@ com.virgilsecurity.crypto parent - 0.10.2-SNAPSHOT + 0.10.2 pythia diff --git a/wrappers/java/ratchet/pom.xml b/wrappers/java/ratchet/pom.xml index 6155eea2e..35202adf6 100755 --- a/wrappers/java/ratchet/pom.xml +++ b/wrappers/java/ratchet/pom.xml @@ -36,7 +36,7 @@ com.virgilsecurity.crypto parent - 0.10.2-SNAPSHOT + 0.10.2 ratchet diff --git a/wrappers/python/setup.py b/wrappers/python/setup.py index 448acd313..a92af8175 100644 --- a/wrappers/python/setup.py +++ b/wrappers/python/setup.py @@ -62,7 +62,7 @@ def is_pure(self): author_email="support@virgilsecurity.com", url="https://virgilsecurity.com", classifiers=[ - "Development Status :: 2 - Pre-Alpha", + "Development Status :: 5 - Production/Stable", "License :: OSI Approved :: BSD License", "Natural Language :: English", "Intended Audience :: Developers", diff --git a/wrappers/python/virgil_crypto_lib/__init__.py b/wrappers/python/virgil_crypto_lib/__init__.py index d5d4369c6..a341f8380 100644 --- a/wrappers/python/virgil_crypto_lib/__init__.py +++ b/wrappers/python/virgil_crypto_lib/__init__.py @@ -34,4 +34,4 @@ __author__ = "Virgil Security" -__version__ = "0.10.2-dev1" +__version__ = "0.10.2" From c65ecd7aca61e3b14a30c85086d8a0e32fd196f0 Mon Sep 17 00:00:00 2001 From: SergeySeroshtan Date: Mon, 9 Sep 2019 07:38:09 +0300 Subject: [PATCH 9/9] Update ChangeLog according to the version v0.10.2 --- ChangeLog.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index 8e58cd1d4..5b7562946 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,6 +1,18 @@ # virgil-crypto-c ChangeLog (Sorted by date) +## Version 0.10.2 released 2019-09-09 + +### Features + +- Lib/Foundation: Added support for managing recipients within MessageInfo +- Lib/PHE: Added PHE Cipher additional data support + +### Changes + +- Wrapper/Java: Run java benchmark with a profile only + + ## Version 0.10.1 released 2019-09-02 ### Bugfix