diff --git a/Jenkinsfile.cd b/Jenkinsfile.cd index 28f95f8ced..8f0ab258c9 100644 --- a/Jenkinsfile.cd +++ b/Jenkinsfile.cd @@ -481,14 +481,13 @@ def linuxVcxJavaTesting(env_name, network_name, testEnv, stashBuildResults) { def linuxVcxPythonTesting(env_name, network_name, testEnv, stashBuildResults) { unstash name: "VcxPythonLibvcxSO${env_name}" unstash name: "VcxPythonLibindyAndLibnullpaySO${env_name}" + dir('vcx/wrappers/python3') { - - testEnv.inside { echo "${env_name} Vcx Test: Test python wrapper" sh ''' - python3.5 -m pip install --user pytest==3.4.2 qrcode pytest-asyncio + python3.5 -m pip install --user pytest==3.6.4 pytest-asyncio LD_LIBRARY_PATH=./:${LD_LIBRARY_PATH} python3.5 -m pytest -s ''' } @@ -564,10 +563,10 @@ def windowsTesting() { stash includes: 'target/release/*.dll', name: 'LibnullpayWindowsBuildResult' } - bat "copy $WORKSPACE\\libnullpay\\target\\release\\nullpay.dll $WORKSPACE\\cli" + bat "PowerShell.exe \"Copy-Item $WORKSPACE/libnullpay/target/release/nullpay.dll -Destination $WORKSPACE/cli\"" dir('cli') { - bat "sed -i -e \"s/10\\.0\\.0\\.2/${INDY_SDK_SERVER_IP}/g\" docker_pool_transactions_genesis" + bat "PowerShell.exe \"&{(Get-Content -Path docker_pool_transactions_genesis -Raw) -replace '10\\.0\\.0\\.2','$INDY_SDK_SERVER_IP'} | Set-Content -Path docker_pool_transactions_genesis\"" def featuresArgs = '' // def featuresArgs = '--features "nullpay_plugin"' // disabled because of IS-1109 @@ -594,10 +593,16 @@ def windowsTesting() { stash includes: 'target/release/indy-cli.exe,target/release/*.dll', name: 'IndyCliWindowsBuildResult' } - bat "copy $WORKSPACE\\libnullpay\\target\\release\\nullpay.dll $WORKSPACE\\vcx\\libvcx" + bat "PowerShell.exe \"Copy-Item $WORKSPACE/libnullpay/target/release/nullpay.dll -Destination $WORKSPACE/vcx/libvcx\"" dir('vcx/libvcx') { echo "Windows Libvcx Test: Build" + + // FIXME remove that once https://jira.hyperledger.org/browse/IS-1127 is resolved + bat """ + PowerShell.exe "&{(Get-Content -Path src/settings.rs -Raw) -replace '/tmp/test_init.json','./test_init.json'} | Set-Content -Path src/settings.rs" + """ + withEnv([ "OPENSSL_DIR=$WORKSPACE\\libindy\\prebuilt", "RUST_BACKTRACE=1" diff --git a/Jenkinsfile.ci b/Jenkinsfile.ci index 3217887935..9b6af5b6e6 100644 --- a/Jenkinsfile.ci +++ b/Jenkinsfile.ci @@ -84,10 +84,10 @@ def windowsTesting() { } } - bat "copy $WORKSPACE\\libnullpay\\target\\debug\\nullpay.dll $WORKSPACE\\cli" + bat "PowerShell.exe \"Copy-Item $WORKSPACE/libnullpay/target/debug/nullpay.dll -Destination $WORKSPACE/cli\"" dir('cli') { - bat "sed -i -e \"s/10\\.0\\.0\\.2/${INDY_SDK_SERVER_IP}/g\" docker_pool_transactions_genesis" + bat "PowerShell.exe \"&{(Get-Content -Path docker_pool_transactions_genesis -Raw) -replace '10\\.0\\.0\\.2','$INDY_SDK_SERVER_IP'} | Set-Content -Path docker_pool_transactions_genesis\"" def featuresArgs = '' // def featuresArgs = '--features "nullpay_plugin"' // disabled because of IS-1109 @@ -109,10 +109,16 @@ def windowsTesting() { } } - bat "copy $WORKSPACE\\libnullpay\\target\\debug\\nullpay.dll $WORKSPACE\\vcx\\libvcx" + bat "PowerShell.exe \"Copy-Item $WORKSPACE/libnullpay/target/debug/nullpay.dll -Destination $WORKSPACE/vcx/libvcx\"" dir('vcx/libvcx') { echo "Windows Libvcx Test: Build" + + // FIXME remove that once https://jira.hyperledger.org/browse/IS-1127 is resolved + bat """ + PowerShell.exe "&{(Get-Content -Path src/settings.rs -Raw) -replace '/tmp/test_init.json','./test_init.json'} | Set-Content -Path src/settings.rs" + """ + withEnv([ "OPENSSL_DIR=$WORKSPACE\\libindy\\prebuilt", "RUST_BACKTRACE=1" @@ -616,7 +622,7 @@ def linuxVcxPythonTesting(env_name, network_name, testEnv) { echo "${env_name} Vcx Test: Test python wrapper" sh ''' - python3.5 -m pip install --user pytest==3.4.2 qrcode pytest-asyncio + python3.5 -m pip install --user pytest==3.6.4 pytest-asyncio LD_LIBRARY_PATH=./:${LD_LIBRARY_PATH} python3.5 -m pytest -s ''' } diff --git a/README.md b/README.md index 59261077e9..620044fa87 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ rewritten but still contains some useful ideas. The major artifact of the SDK is a C-callable library that provides the basic building blocks for the creation of applications on the top of [Hyperledger Indy](https://www.hyperledger.org/projects/hyperledger-indy). -It is available for most popular desktop, mobile and server platfrorms. +It is available for most popular desktop, mobile and server platforms. ### Libindy wrappers diff --git a/cli/src/commands/ledger.rs b/cli/src/commands/ledger.rs index ee872d6f58..fded7d2004 100644 --- a/cli/src/commands/ledger.rs +++ b/cli/src/commands/ledger.rs @@ -271,7 +271,7 @@ pub mod schema_command { command!(CommandMetadata::build("schema", "Send Schema transaction to the Ledger.") .add_required_param("name", "Schema name") .add_required_param("version", "Schema version") - .add_required_param("attr_names", "Schema attributes split by comma") + .add_required_param("attr_names", "Schema attributes split by comma (the number of attributes should be less or equal than 125)") .add_optional_param("fees_inputs","The list of source inputs") .add_optional_param("fees_outputs","The list of outputs in the following format: (recipient, amount)") .add_optional_param("extra","Optional information for fees payment operation") diff --git a/doc/rhel-build.md b/doc/rhel-build.md index dd64d4aec9..1ae8bf8a34 100644 --- a/doc/rhel-build.md +++ b/doc/rhel-build.md @@ -42,7 +42,7 @@ dnf install -y \ For Amazon Linux 2017.03 or other distributions without `libsodium` available in system repositories: ``` cd /tmp -curl https://download.libsodium.org/libsodium/releases/libsodium-1.0.14.tar.gz | tar -xz +curl https://download.libsodium.org/libsodium/releases/old/libsodium-1.0.14.tar.gz | tar -xz cd /tmp/libsodium-1.0.14 ./configure make diff --git a/doc/ubuntu-build.md b/doc/ubuntu-build.md index 474eeee7a7..3ad424ff42 100644 --- a/doc/ubuntu-build.md +++ b/doc/ubuntu-build.md @@ -19,7 +19,7 @@ Because of this, it requires to build and install `libsodium` from source: ``` cd /tmp && \ - curl https://download.libsodium.org/libsodium/releases/libsodium-1.0.14.tar.gz | tar -xz && \ + curl https://download.libsodium.org/libsodium/releases/old/libsodium-1.0.14.tar.gz | tar -xz && \ cd /tmp/libsodium-1.0.14 && \ ./configure --disable-shared && \ make && \ diff --git a/doc/windows-build.md b/doc/windows-build.md index 375ba46d2d..e09b0f5265 100644 --- a/doc/windows-build.md +++ b/doc/windows-build.md @@ -43,7 +43,7 @@ git clone https://github.com/hyperledger/indy-sdk.git ### Binary deps - https://www.npcglib.org/~stathis/downloads/openssl-1.0.2k-vs2017.7z -- https://download.libsodium.org/libsodium/releases/libsodium-1.0.14-msvc.zip +- https://download.libsodium.org/libsodium/releases/old/libsodium-1.0.14-msvc.zip ### Source deps diff --git a/libindy/Cargo.lock b/libindy/Cargo.lock index 4550c9d9e5..393116fa19 100644 --- a/libindy/Cargo.lock +++ b/libindy/Cargo.lock @@ -50,7 +50,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "arrayvec" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -71,19 +71,19 @@ name = "backtrace" version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace-sys 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "backtrace-sys" -version = "0.1.26" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -106,7 +106,7 @@ name = "blake2-rfc" version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -136,7 +136,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cc" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -151,7 +151,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -180,29 +180,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "criterion-plot 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "criterion-plot 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "criterion-stats 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "csv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", "itertools-num 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)", "simplelog 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "criterion-plot" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -214,7 +216,7 @@ dependencies = [ "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "thread-scoped 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -224,7 +226,7 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "csv-core 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -242,7 +244,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.23 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -327,21 +329,21 @@ dependencies = [ [[package]] name = "failure" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "failure_derive" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.23 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -406,8 +408,8 @@ dependencies = [ "pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -427,7 +429,7 @@ dependencies = [ name = "indy" version = "1.7.0" dependencies = [ - "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "indy-sys 1.7.0", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -450,12 +452,12 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.10.12 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -548,14 +550,14 @@ dependencies = [ "rmp-serde 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)", "rusqlite 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "rust-base58 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "sodiumoxide 0.0.16 (registry+https://github.com/rust-lang/crates.io-index)", "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "zmq 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -574,7 +576,7 @@ name = "libsqlite3-sys" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -694,7 +696,7 @@ dependencies = [ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.23 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -763,7 +765,7 @@ name = "openssl-sys" version = "0.9.40" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -830,22 +832,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand_core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "redox_syscall" -version = "0.1.44" +version = "0.1.50" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -853,7 +870,7 @@ name = "redox_termios" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -862,9 +879,9 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -903,7 +920,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "rmp 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -914,7 +931,7 @@ dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "libsqlite3-sys 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -927,7 +944,7 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -955,27 +972,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.82" +version = "1.0.84" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.82" +version = "1.0.84" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.23 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.33" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1017,7 +1034,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", "libsodium-sys 0.0.16 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1042,7 +1059,7 @@ dependencies = [ [[package]] name = "syn" -version = "0.15.23" +version = "0.15.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1065,7 +1082,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.23 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1092,7 +1109,7 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)", "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1127,11 +1144,11 @@ dependencies = [ [[package]] name = "time" -version = "0.1.41" +version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1266,10 +1283,10 @@ dependencies = [ "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" -"checksum arrayvec 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d18513977c2d8261c448511c5c53dc66b26dfccbc3d4446672dea1e71a7d8a26" +"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" "checksum backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "18b65ea1161bfb2dd6da6fade5edd4dbd08fba85012123dd333d2fd1b90b2782" -"checksum backtrace-sys 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "3fcce89e5ad5c8949caa9434501f7b55415b3e7ad5270cb88c75a8d35e8f1279" +"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6" "checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" @@ -1277,13 +1294,13 @@ dependencies = [ "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" "checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d" "checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" -"checksum cc 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "155ed195f7bd722d1dfeb30365b9d0c1f6a078fa7ca4014497e5935d90993d6f" +"checksum cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4a8b715cb4597106ea87c7c84b2f1d452c7492033765df7f32651e66fcf749" "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" "checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" "checksum criterion 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c47d2b548c5647e1a436dc0cb78d4ebf51b6bf7ab101ed76662828bdd4d3a24a" -"checksum criterion-plot 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6e649d6aacdbbdb94ec659561a309a71336fc5655ed408f3afd28df2fc0c4f4f" +"checksum criterion-plot 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "dd5f81689739e463ece7a6b62c6ec63bdab5c4e28fe05ff451769e87d1511411" "checksum criterion-stats 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ff43cac80562f91ead0b617c1be74edf350adfaa195809d355de98dfc8f9237d" "checksum csv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd1c44c58078cfbeaf11fbb3eac9ae5534c23004ed770cc4bfb48e658ae4f04" "checksum csv-core 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa5cdef62f37e6ffe7d1f07a381bc0db32b7a3ff1cac0de56cb0d81e71f53d65" @@ -1298,8 +1315,8 @@ dependencies = [ "checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" "checksum etcommon-hexutil 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "20b4d1933bf88b806ba2d9189880b1b4ef205e42df9573b65716f2a50818024c" "checksum etcommon-rlp 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "804a932fed78022b8ec25c06576c57f683a6646dfae22f93dcc5d23470aafe85" -"checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7" -"checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596" +"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" +"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" @@ -1353,8 +1370,10 @@ dependencies = [ "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c" "checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" -"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" -"checksum redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "a84bcd297b87a545980a2d25a0beb72a1f490c31f0a9fde52fca35bfbb1ceb70" +"checksum rand 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dee497e66d8d76bf08ce20c8d36e16f93749ab0bf89975b4f8ae5cee660c2da2" +"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db" +"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +"checksum redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)" = "52ee9a534dc1301776eff45b4fa92d2c39b1d8c3d3357e6eb593e0d795506fc2" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum redox_users 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "214a97e49be64fd2c86f568dd0cb2c757d2cc53de95b273b6ad0a1c908482f26" "checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f" @@ -1363,14 +1382,14 @@ dependencies = [ "checksum rmp-serde 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)" = "011e1d58446e9fa3af7cdc1fb91295b10621d3ac4cb3a85cc86385ee9ca50cd3" "checksum rusqlite 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9409d78a5a9646685688266e1833df8f08b71ffcae1b5db6c1bfb5970d8a80f" "checksum rust-base58 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b313b91fcdc6719ad41fa2dad2b7e810b03833fae4bf911950e15529a5f04439" -"checksum rustc-demangle 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "01b90379b8664dd83460d59bdc5dd1fd3172b8913788db483ed1325171eab2f7" +"checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619" "checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" "checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" "checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" -"checksum serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)" = "6fa52f19aee12441d5ad11c9a00459122bd8f98707cadf9778c540674f1935b6" -"checksum serde_derive 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)" = "96a7f9496ac65a2db5929afa087b54f8fc5008dcfbe48a8874ed20049b0d6154" -"checksum serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "c37ccd6be3ed1fdf419ee848f7c758eb31b054d7cd3ae3600e3bae0adf569811" +"checksum serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)" = "0e732ed5a5592c17d961555e3b552985baf98d50ce418b7b655f31f6ba7eb1b7" +"checksum serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d6115a3ca25c224e409185325afc16a0d5aaaabc15c42b09587d6f1ba39a5b" +"checksum serde_json 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)" = "bdf540260cfee6da923831f4776ddc495ada940c30117977c70f1313a6130545" "checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0" "checksum sha3 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b64dcef59ed4290b9fb562b53df07f564690d6539e8ecdd4728cf392477530bc" "checksum simplelog 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e95345f185d5adeb8ec93459d2dc99654e294cc6ccf5b75414d8ea262de9a13" @@ -1378,7 +1397,7 @@ dependencies = [ "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -"checksum syn 0.15.23 (registry+https://github.com/rust-lang/crates.io-index)" = "9545a6a093a3f0bd59adb472700acc08cad3776f860f16a897dfce8c88721cbc" +"checksum syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)" = "734ecc29cd36e8123850d9bf21dfd62ef8300aaa8f879aabaa899721808be37c" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" "checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561" @@ -1388,7 +1407,7 @@ dependencies = [ "checksum thread-scoped 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bcbb6aa301e5d3b0b5ef639c9a9c7e2f1c944f177b460c04dc24c69b1fa2bd99" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" -"checksum time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "847da467bf0db05882a9e2375934a8a55cffdc9db0d128af1518200260ba1f6c" +"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "736b60249cb25337bc196faa43ee12c705e426f3d55c214d73a4e7be06f92cb4" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" "checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" diff --git a/libindy/ci/amazon.dockerfile b/libindy/ci/amazon.dockerfile index 87a4575e36..80329b91de 100755 --- a/libindy/ci/amazon.dockerfile +++ b/libindy/ci/amazon.dockerfile @@ -22,7 +22,7 @@ RUN curl --silent --location https://rpm.nodesource.com/setup_8.x | bash - RUN yum -y install nodejs RUN cd /tmp && \ - curl https://download.libsodium.org/libsodium/releases/libsodium-1.0.14.tar.gz | tar -xz && \ + curl https://download.libsodium.org/libsodium/releases/old/libsodium-1.0.14.tar.gz | tar -xz && \ cd /tmp/libsodium-1.0.14 && \ ./configure && \ make && \ diff --git a/libindy/ci/ubuntu.dockerfile b/libindy/ci/ubuntu.dockerfile index 7807348c48..896248128c 100755 --- a/libindy/ci/ubuntu.dockerfile +++ b/libindy/ci/ubuntu.dockerfile @@ -39,7 +39,7 @@ RUN pip3 install -U \ deb-pkg-tools RUN cd /tmp && \ - curl https://download.libsodium.org/libsodium/releases/libsodium-1.0.14.tar.gz | tar -xz && \ + curl https://download.libsodium.org/libsodium/releases/old/libsodium-1.0.14.tar.gz | tar -xz && \ cd /tmp/libsodium-1.0.14 && \ ./configure --disable-shared && \ make && \ diff --git a/libindy/include/indy_agent.h b/libindy/include/indy_agent.h deleted file mode 100644 index eddc22a767..0000000000 --- a/libindy/include/indy_agent.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __indy__agent__included__ -#define __indy__agent__included__ - -#ifdef __cplusplus -extern "C" { -#endif - - extern indy_error_t indy_pack_message(indy_handle_t command_handle, - indy_handle_t wallet_handle, - const char *const , - - void (*cb)(indy_handle_t command_handle, - indy_error_t err, - const char *const vk) - ); \ No newline at end of file diff --git a/libindy/include/indy_crypto.h b/libindy/include/indy_crypto.h index 8ef0a525b8..3c2d777ae6 100644 --- a/libindy/include/indy_crypto.h +++ b/libindy/include/indy_crypto.h @@ -317,6 +317,123 @@ extern "C" { indy_u32_t decrypted_msg_len) ); + + /// Packs a message + /// + /// Note to use DID keys with this function you can call indy_key_for_did to get key id (verkey) + /// for specific DID. + /// + /// #Params + /// command_handle: command handle to map callback to user context. + /// message: a pointer to the first byte of the message to be packed + /// message_len: the length of the message + /// receivers: a string in the format of a json list which will contain the list of receiver's keys + /// the message is being encrypted for. + /// Example: + /// "[, ]" + /// sender: the sender's verkey as a string When "" is used in this parameter, anoncrypt is used + /// cb: Callback that takes command result as parameter. + /// + /// #Returns + /// a JWE using authcrypt alg is defined below: + /// { + /// "protected": "b64URLencoded({ + /// "enc": "xsalsa20poly1305", + /// "typ": "JWM/1.0", + /// "alg": "authcrypt", + /// "recipients": [ + /// { + /// "encrypted_key": anoncrypt(encrypted_cek|sender_vk|nonce) + /// "header": { + /// "kid": "b64URLencode(ver_key)" + /// } + /// }, + /// ], + /// })" + /// "iv": , + /// "ciphertext": , + /// "tag": + /// } + /// + /// Alternative example in using anoncrypt alg is defined below: + /// { + /// "protected": "b64URLencode({ + /// "enc": "xsalsa20poly1305", + /// "typ": "JWM/1.0", + /// "alg": "anoncrypt", + /// "recipients": [ + /// { + /// "encrypted_key": , + /// "header": { + /// "kid": "b64URLencode(ver_key)" + /// } + /// }, + /// ], + /// })" + /// "iv": , + /// "ciphertext": , + /// "tag": + /// } + /// + /// + /// #Errors + /// Common* + /// Wallet* + /// Ledger* + /// Crypto* + extern indy_error_t indy_pack_message(indy_handle_t command_handle, + indy_handle_t wallet_handle, + const indy_u8_t* message, + indy_u64_t message_len, + const char * receiver_keys, + const char * sender, + + void (*cb)(indy_handle_t command_handle_, + indy_error_t err, + const indy_u8_t* jwe_msg_raw, + indy_u64_t jwe_msg_len) + ); + + + /// Unpacks a message packed using indy_pack_message which follows the wire message format HIPE + /// + /// + /// #Params + /// command_handle: command handle to map callback to user context. + /// jwe_data: a pointer to the first byte of the JWE to be unpacked + /// jwe_len: the length of the JWE message in bytes + /// cb: Callback that takes command result as parameter. + /// + /// #Returns + /// if authcrypt was used to pack the message returns this json structure: + /// { + /// message: , + /// sender_verkey: + /// } + /// + /// OR + /// + /// if anoncrypt was used to pack the message returns this json structure: + /// { + /// message: , + /// } + /// + /// + /// #Errors + /// Common* + /// Wallet* + /// Ledger* + /// Crypto* + extern indy_error_t indy_unpack_message(indy_handle_t command_handle, + indy_handle_t wallet_handle, + const indy_u8_t* jwe_msg, + indy_u64_t jwe_len, + + void (*cb)(indy_handle_t command_handle_, + indy_error_t err, + const indy_u8_t* res_json_raw, + indy_u64_t res_json_len) + ); #ifdef __cplusplus } #endif diff --git a/libindy/include/indy_ledger.h b/libindy/include/indy_ledger.h index 383ff35ed6..d2a511ab06 100644 --- a/libindy/include/indy_ledger.h +++ b/libindy/include/indy_ledger.h @@ -313,7 +313,7 @@ extern "C" { /// data: Credential schema. /// { /// id: identifier of schema - /// attrNames: array of attribute name strings + /// attrNames: array of attribute name strings (the number of attributes should be less or equal than 125) /// name: Schema's name string /// version: Schema's version string, /// ver: Version of the Schema json diff --git a/libindy/src/api/agent.rs b/libindy/src/api/agent.rs deleted file mode 100644 index 874be55642..0000000000 --- a/libindy/src/api/agent.rs +++ /dev/null @@ -1,206 +0,0 @@ -//extern crate libc; -// -//use api::ErrorCode; -//use commands::agent::AgentCommand; -//use commands::{Command, CommandExecutor}; -//use errors::ToErrorCode; -//use utils::ctypes; -// -//use self::libc::c_char; -// -///// Verify a signature with a verkey. -///// -///// Note to use DID keys with this function you can call indy_key_for_did to get key id (verkey) -///// for specific DID. -///// -///// #Params -///// command_handle: command handle to map callback to user context. -///// wallet_handle: wallet identifier containing the key of the sender's private key -///// message: the message which is going to be packed up -///// receiver_keys: a string in the format of a json list which will contain the list of receiver's keys -///// the message is being encrypted for. For example: -///// "[, ]" -///// cb: Callback that takes command result as parameter. -///// -///// #Returns -///// a JWE in the format defined below: -///// { -///// "protected": "b64URLencoded({ -///// "enc": "xsalsa20poly1305", -///// "typ": "JWM/1.0", -///// "aad_hash_alg": "BLAKE2b", -///// "cek_enc": "authcrypt" -///// })" -///// "recipients": [ -///// { -///// "encrypted_key": , -///// "header": { -///// "sender": , -///// "kid": "did:sov:1234512345#key-id", -///// "key": "b64URLencode(ver_key)" -///// } -///// }, -///// ], -///// "aad": , -///// "iv": , -///// "ciphertext": , -///// "tag": -///// } -///// -///// #Errors -///// Common* -///// Wallet* -///// Ledger* -///// Crypto* -// -// -//#[no_mangle] -//pub fn indy_auth_pack_message( -// command_handle: i32, -// wallet_handle: i32, -// message: *const c_char, -// receiver_keys: *const c_char, -// sender: *const c_char, -// cb: Option, -//) -> ErrorCode { -// trace!("indy_auth_pack_message: >>> wallet_handle: {:?}, message: {:?}, receiver_keys: {:?}, sender: {:?}", -// wallet_handle, message, receiver_keys, sender); -// -// check_useful_c_str!(message, ErrorCode::CommonInvalidParam3); -// check_useful_c_str!(receiver_keys, ErrorCode::CommonInvalidParam4); -// check_useful_c_str!(sender, ErrorCode::CommonInvalidParam5); -// check_useful_c_callback!(cb, ErrorCode::CommonInvalidParam6); -// -// trace!("indy_auth_pack_message: entities >>> wallet_handle: {:?}, message: {:?}, receiver_keys: {:?}, sender: {:?}", -// wallet_handle, message, receiver_keys, sender); -// -// let result = CommandExecutor::instance().send(Command::Agent(AgentCommand::AuthPackMessage( -// message, -// receiver_keys, -// sender, -// wallet_handle, -// Box::new(move |result| { -// let (err, jwe) = result_to_err_code_1!(result, String::new()); -// trace!( -// "indy_auth_pack_message: cb command_handle: {:?}, err: {:?}, jwe: {:?}", -// command_handle, -// err, -// jwe -// ); -// let jwe = ctypes::string_to_cstring(jwe); -// cb(command_handle, err, jwe.as_ptr()) -// }), -// ))); -// -// let res = result_to_err_code!(result); -// -// trace!("indy_auth_pack_message: <<< res: {:?}", res); -// -// res -//} -// -//#[no_mangle] -//pub fn indy_anon_pack_message( -// command_handle: i32, -// message: *const c_char, -// receiver_keys: *const c_char, -// cb: Option, -//) -> ErrorCode { -// trace!( -// "indy_anon_pack_message: >>> message: {:?}, receiver_keys: {:?}", -// message, -// receiver_keys -// ); -// -// check_useful_c_str!(message, ErrorCode::CommonInvalidParam3); -// check_useful_c_str!(receiver_keys, ErrorCode::CommonInvalidParam4); -// check_useful_c_callback!(cb, ErrorCode::CommonInvalidParam5); -// -// trace!( -// "indy_anon_pack_message: entities >>> message: {:?}, receiver_keys: {:?}", -// message, -// receiver_keys -// ); -// -// let result = CommandExecutor::instance().send(Command::Agent(AgentCommand::AnonPackMessage( -// message, -// receiver_keys, -// Box::new(move |result| { -// let (err, jwe) = result_to_err_code_1!(result, String::new()); -// trace!( -// "indy_anon_pack_message: cb command_handle: {:?}, err: {:?}, jwe: {:?}", -// command_handle, -// err, -// jwe -// ); -// let verkey = ctypes::string_to_cstring(jwe); -// cb(command_handle, err, verkey.as_ptr()) -// }), -// ))); -// -// let res = result_to_err_code!(result); -// -// trace!("indy_anon_pack_message: <<< res: {:?}", res); -// -// res -//} -// -////update function to return key used -//#[no_mangle] -//pub fn indy_unpack_message( -// command_handle: i32, -// wallet_handle: i32, -// jwe: *const c_char, -// sender: *const c_char, -// cb: Option< -// extern "C" fn( -// xcommand_handle: i32, -// err: ErrorCode, -// plaintext: *const c_char, -// sender_vk: *const c_char, -// ), -// >, -//) -> ErrorCode { -// trace!( -// "indy_unpack_message: >>> wallet_handle: {:?}, jwe: {:?}, sender: {:?}", -// wallet_handle, -// jwe, -// sender -// ); -// -// check_useful_c_str!(jwe, ErrorCode::CommonInvalidParam3); -// check_useful_c_str!(sender, ErrorCode::CommonInvalidParam4); -// check_useful_c_callback!(cb, ErrorCode::CommonInvalidParam5); -// -// trace!( -// "indy_unpack_message: entities >>> wallet_handle: {:?}, jwe: {:?}, sender: {:?}", -// wallet_handle, -// jwe, -// sender -// ); -// -// let result = CommandExecutor::instance().send(Command::Agent(AgentCommand::UnpackMessage( -// jwe, -// sender, -// wallet_handle, -// Box::new(move |result| { -// let (err, plaintext, sender_vk) = -// result_to_err_code_2!(result, String::new(), String::new()); -// trace!( -// "indy_unpack_message: cb command_handle: {:?}, err: {:?}, plaintext: {:?}", -// command_handle, -// err, -// plaintext -// ); -// let plaintext = ctypes::string_to_cstring(plaintext); -// let sender_vk = ctypes::string_to_cstring(sender_vk); -// cb(command_handle, err, plaintext.as_ptr(), sender_vk.as_ptr()) -// }), -// ))); -// -// let res = result_to_err_code!(result); -// -// trace!("indy_unpack_message: <<< res: {:?}", res); -// -// res -//} diff --git a/libindy/src/api/anoncreds.rs b/libindy/src/api/anoncreds.rs index 2707f0b338..ee4ac96107 100644 --- a/libindy/src/api/anoncreds.rs +++ b/libindy/src/api/anoncreds.rs @@ -42,7 +42,7 @@ use std::collections::HashMap; /// issuer_did: DID of schema issuer /// name: a name the schema /// version: a version of the schema -/// attrs: a list of schema attributes descriptions +/// attrs: a list of schema attributes descriptions (the number of attributes should be less or equal than 125) /// cb: Callback that takes command result as parameter /// /// #Returns diff --git a/libindy/src/api/crypto.rs b/libindy/src/api/crypto.rs index 4dd78b4288..91e8d1f353 100644 --- a/libindy/src/api/crypto.rs +++ b/libindy/src/api/crypto.rs @@ -557,4 +557,190 @@ pub extern fn indy_crypto_anon_decrypt(command_handle: IndyHandle, trace!("indy_crypto_anon_decrypt: <<< res: {:?}", res); res -} \ No newline at end of file +} + +/// Packs a message +/// +/// Note to use DID keys with this function you can call indy_key_for_did to get key id (verkey) +/// for specific DID. +/// +/// #Params +/// command_handle: command handle to map callback to user context. +/// message: a pointer to the first byte of the message to be packed +/// message_len: the length of the message +/// receivers: a string in the format of a json list which will contain the list of receiver's keys +/// the message is being encrypted for. +/// Example: +/// "[, ]" +/// sender: the sender's verkey as a string When "" is used in this parameter, anoncrypt is used +/// cb: Callback that takes command result as parameter. +/// +/// #Returns +/// a JWE using authcrypt alg is defined below: +/// { +/// "protected": "b64URLencoded({ +/// "enc": "xsalsa20poly1305", +/// "typ": "JWM/1.0", +/// "alg": "authcrypt", +/// "recipients": [ +/// { +/// "encrypted_key": anoncrypt(encrypted_cek|sender_vk|nonce) +/// "header": { +/// "kid": "b64URLencode(ver_key)" +/// } +/// }, +/// ], +/// })" +/// "iv": , +/// "ciphertext": , +/// "tag": +/// } +/// +/// Alternative example in using anoncrypt alg is defined below: +/// { +/// "protected": "b64URLencode({ +/// "enc": "xsalsa20poly1305", +/// "typ": "JWM/1.0", +/// "alg": "anoncrypt", +/// "recipients": [ +/// { +/// "encrypted_key": , +/// "header": { +/// "kid": "b64URLencode(ver_key)" +/// } +/// }, +/// ], +/// })" +/// "iv": , +/// "ciphertext": , +/// "tag": +/// } +/// +/// +/// #Errors +/// Common* +/// Wallet* +/// Ledger* +/// Crypto* +#[no_mangle] +pub extern fn indy_pack_message( + command_handle: i32, + wallet_handle: i32, + message: *const u8, + message_len: u32, + receiver_keys: *const c_char, + sender: *const c_char, + cb: Option, +) -> ErrorCode { + trace!("indy_pack_message: >>> wallet_handle: {:?}, message: {:?}, message_len {:?},\ + receiver_keys: {:?}, sender: {:?}", wallet_handle, message, message_len, receiver_keys, sender); + + check_useful_c_byte_array!(message, message_len, ErrorCode::CommonInvalidParam2, ErrorCode::CommonInvalidParam3); + check_useful_c_str!(receiver_keys, ErrorCode::CommonInvalidParam4); + check_useful_c_str_empty_accepted!(sender, ErrorCode::CommonInvalidParam5); + check_useful_c_callback!(cb, ErrorCode::CommonInvalidParam6); + + trace!("indy_pack_message: entities >>> wallet_handle: {:?}, message: {:?}, message_len {:?},\ + receiver_keys: {:?}, sender: {:?}", wallet_handle, message, message_len, receiver_keys, sender); + + let result = CommandExecutor::instance().send(Command::Crypto(CryptoCommand::PackMessage( + message, + receiver_keys, + sender, + wallet_handle, + Box::new(move |result| { + let (err, jwe) = result_to_err_code_1!(result, Vec::new()); + trace!("indy_auth_pack_message: jwe: {:?}", jwe); + let (jwe_data, jwe_len) = ctypes::vec_to_pointer(&jwe); + cb(command_handle, err, jwe_data, jwe_len) + }), + ))); + + let res = result_to_err_code!(result); + + trace!("indy_auth_pack_message: <<< res: {:?}", res); + + res +} + + +/// Unpacks a message packed using indy_pack_message which follows the wire message format +/// +/// +/// #Params +/// command_handle: command handle to map callback to user context. +/// jwe_data: a pointer to the first byte of the JWE to be unpacked +/// jwe_len: the length of the JWE message in bytes +/// cb: Callback that takes command result as parameter. +/// +/// #Returns +/// if authcrypt was used to pack the message returns this json structure: +/// { +/// message: , +/// sender_verkey: +/// } +/// +/// OR +/// +/// if anoncrypt was used to pack the message returns this json structure: +/// { +/// message: , +/// } +/// +/// +/// #Errors +/// Common* +/// Wallet* +/// Ledger* +/// Crypto* +#[no_mangle] +pub extern fn indy_unpack_message( + command_handle: i32, + wallet_handle: i32, + jwe_data: *const u8, + jwe_len: u32, + cb: Option< + extern "C" fn( + xcommand_handle: i32, + err: ErrorCode, + res_json_data : *const u8, + res_json_len : u32 + ), + >, +) -> ErrorCode { + trace!( + "indy_unpack_message: >>> wallet_handle: {:?}, jwe_data: {:?}, jwe_len {:?}", + wallet_handle, + jwe_data, + jwe_len + ); + + check_useful_c_byte_array!(jwe_data, jwe_len, ErrorCode::CommonInvalidParam2, ErrorCode::CommonInvalidParam3); + check_useful_c_callback!(cb, ErrorCode::CommonInvalidParam4); + + trace!( + "indy_unpack_message: entities >>> wallet_handle: {:?}, jwe_data: {:?}, jwe_len {:?}", + wallet_handle, + jwe_data, + jwe_len + ); + + let result = CommandExecutor::instance().send(Command::Crypto(CryptoCommand::UnpackMessage( + jwe_data, + wallet_handle, + Box::new(move |result| { + let (err, res_json) = result_to_err_code_1!(result, Vec::new()); + trace!("indy_unpack_message: cb command_handle: {:?}, err: {:?}, res_json: {:?}", + command_handle, err, res_json + ); + let (res_json_data, res_json_len) = ctypes::vec_to_pointer(&res_json); + cb(command_handle, err, res_json_data, res_json_len) + }), + ))); + + let res = result_to_err_code!(result); + + trace!("indy_unpack_message: <<< res: {:?}", res); + + res +} diff --git a/libindy/src/api/ledger.rs b/libindy/src/api/ledger.rs index b9a53f81f6..df1ef5b654 100644 --- a/libindy/src/api/ledger.rs +++ b/libindy/src/api/ledger.rs @@ -594,7 +594,7 @@ pub extern fn indy_build_get_attrib_request(command_handle: IndyHandle, /// data: Credential schema. /// { /// id: identifier of schema -/// attrNames: array of attribute name strings +/// attrNames: array of attribute name strings (the number of attributes should be less or equal than 125) /// name: Schema's name string /// version: Schema's version string, /// ver: Version of the Schema json diff --git a/libindy/src/api/mod.rs b/libindy/src/api/mod.rs index c564b3b2b7..e0b3f3b1c1 100644 --- a/libindy/src/api/mod.rs +++ b/libindy/src/api/mod.rs @@ -12,7 +12,6 @@ pub mod blob_storage; pub mod non_secrets; pub mod payments; pub mod logger; -pub mod agent; use self::libc::c_char; @@ -240,26 +239,6 @@ pub enum ErrorCode // Extra funds on inputs PaymentExtraFundsError = 705, - // Failed to perform Encryption or Decryption while routing messages - RouteEncryptionError = 800, - - // Failed to Encode the data properly while routing messages - RouteEncodeError = 801, - - //Failed to Decode the data properly while routing messages - RouteDecodeError = 802, - - // Failed to unpack the JWM - RouteUnpackError = 803, - - // Failed to pack the JWM - RoutePackError = 804, - - // Key was included when it shouldn't have been - RouteMissingKeyError = 805, - - // Failed to serialize a JWM based on the parameters provided - RouteSerializationError = 806 } /// Set libindy runtime configuration. Can be optionally called to change current params. diff --git a/libindy/src/commands/agent.rs b/libindy/src/commands/agent.rs deleted file mode 100644 index 9db05c7127..0000000000 --- a/libindy/src/commands/agent.rs +++ /dev/null @@ -1,320 +0,0 @@ -use errors::agent::AgentError; -use serde_json; -use domain::agent::AuthAMES; -use domain::agent::AnonRecipient; -use domain::agent::AnonAMES; -use domain::crypto::key::Key; -use errors::common::CommonError; -use errors::indy::IndyError; -use services::crypto::CryptoService; -use services::agent::AgentService; -use services::wallet::WalletService; -use services::wallet::RecordOptions; -use std::rc::Rc; -use std::result; -use utils::crypto::base64; -use domain::agent::FromAddress; -use domain::agent::ToAddress; -use domain::agent::Recipient; -use utils::crypto::base58; -use domain::agent::Header; - -type Result = result::Result; - -pub enum AgentCommand { - AuthPackMessage( - String, // plaintext message - String, //list of receiving keys - String, //my verkey - i32, //wallet_handle - Box) + Send>, - ), - AnonPackMessage( - String, // plaintext message - String, // list of receiving keys - Box) + Send>, - ), - UnpackMessage( - String, // JWE - String, // my verkey - i32, // wallet handle - Box) + Send>, - ), -} - -pub struct AgentCommandExecutor { - wallet_service: Rc, - crypto_service: Rc, - agent_service: Rc, -} - -impl AgentCommandExecutor { - pub fn new( - wallet_service: Rc, - crypto_service: Rc, - agent_service: Rc, - ) -> AgentCommandExecutor { - AgentCommandExecutor { - wallet_service, - crypto_service, - agent_service, - } - } - - pub fn execute(&self, command: AgentCommand) { - match command { - AgentCommand::AuthPackMessage(message, receiver_keys_json, sender_verkey, wallet_handle, cb) => { - info!("PackMessage command received"); - cb(self.auth_pack_msg(&message, &receiver_keys_json, &sender_verkey, wallet_handle)); - } - AgentCommand::AnonPackMessage(message, receiver_keys_json, cb) => { - info!("PackMessage command received"); - cb(self.anon_pack_msg(&message, &receiver_keys_json)); - } - AgentCommand::UnpackMessage(jwe, sender_verkey, wallet_handle, cb) => { - info!("UnpackMessage command received"); - cb(self.unpack_msg(&jwe, &sender_verkey, wallet_handle)); - } - }; - } - -// //TODO change errors -// pub fn auth_pack_msg( -// &self, -// message: &str, -// receiver_keys_json: &str, -// sender_verkey: &str, -// wallet_handle: i32, -// ) -> Result { -// //convert type from json array to Vec -// let recv_keys: Vec<&str> = serde_json::from_str(receiver_keys_json).map_err(|err| { -// IndyError::CommonError(CommonError::InvalidParam4(format!("Failed to serialize recv_keys {:?}", err))) -// })?; -// -// //encrypt ciphertext -// let (sym_key, iv, ciphertext) = self.crypto_service.encrypt_ciphertext(message); -// -// //convert sender_vk to Key -// let my_key: Key = self.wallet_service.get_indy_object(wallet_handle, sender_verkey, &RecordOptions::id_value())?; -// -// //encrypt ceks -// let mut auth_recipients = vec![]; -// -// for their_vk in recv_keys { -// auth_recipients.push( -// self.crypto_service -// .auth_encrypt_recipient(&my_key, their_vk, &sym_key) -// .map_err(|err| { -// IndyError::CommonError(CommonError::InvalidStructure(format!("Invalid anon_recipient structure: {}", err))) -// })?, -// ); -// } -// -// //serialize AuthAMES -// let jwe_json = AuthAMES { -// recipients: auth_recipients, -// ver: "AuthAMES/1.0/".to_string(), -// enc: "xsalsa20poly1305".to_string(), -// ciphertext: base64::encode(ciphertext.as_slice()), -// iv: base64::encode(&iv[..]), -// }; -// serde_json::to_string(&jwe_json) -// .map_err(|err| IndyError::CommonError(CommonError::InvalidStructure(format!("Failed to serialize JWE {}", err)))) -// } -// -// pub fn anon_pack_msg(&self, message: &str, receiver_keys_json: &str) -> Result { -// //convert type from json array to Vec<&str> -// let recv_keys: Vec<&str> = serde_json::from_str(receiver_keys_json).map_err(|err| { -// IndyError::CommonError(CommonError::InvalidParam4(format!("Failed to serialize recv_keys {:?}", err))) -// })?; -// -// //encrypt ciphertext -// let (sym_key, iv, ciphertext) = self.crypto_service.encrypt_ciphertext(message); -// -// //encrypt ceks -// let mut anon_recipients: Vec = vec![]; -// -// for their_vk in recv_keys { -// anon_recipients.push( -// self.crypto_service -// .anon_encrypt_recipient(their_vk, sym_key.clone()) -// .map_err(|err| { -// IndyError::AgentError(AgentError::CommonError(CommonError::InvalidStructure(format!("Invalid anon_recipient structure: {}", err)))) -// })?, -// ); -// } -// -// //serialize AnonAMES -// let anon_ames_struct = AnonAMES { -// recipients: anon_recipients, -// ver: "AnonAMES/1.0/".to_string(), -// enc: "xsalsa20poly1305".to_string(), -// ciphertext: base64::encode(ciphertext.as_slice()), -// iv: base64::encode(&iv[..]), -// }; -// serde_json::to_string(&anon_ames_struct) -// .map_err(|err| IndyError::AgentError(AgentError::PackError(format!("Failed to serialize JWE {}", err)))) -// } -~~~` - pub fn pack_msg( - &self, - message: &[u8], - receivers: &str, - sender: Option<&str> - ) -> Result { - - // encrypt ciphertext - let (sym_key, iv, ciphertext) = self.crypto_service.encrypt_ciphertext(message); - - //list of ceks used to construct JWE later - let mut encrypted_recipients_struct: Vec = vec![]; - - match sender { - Some(s) => { - //parse senders and receivers to structs - let from_address : Result = serde_json::from_str(s) - .map_err(|err| { - IndyError::AgentError(AgentError::PackError(format!("Failed to deserialize sender {}", err))) - }); - let to_address : Result = serde_json::from_str(receivers) - .map_err(|err| { - IndyError::AgentError(AgentError::PackError(format!("Failed to deserialize receivers {}", err))) - }); - - //encrypt sym_key for recipient - for their_vk in receivers_list { - let (e_cek, cek_nonce) = self.crypto_service - .crypto_box(my_key, their_vk, &sym_key[..])?; - - //serialize enc_header - let sender_vk_bytes = base58::decode(&my_key.verkey) - .map_err(|err| { - IndyError::CommonError(err) - })?; - - //encrypt enc_from - let enc_sender = self.crypto_service. - crypto_box_seal(recp_vk, sender_vk_bytes.as_slice())?; - - //create recipient struct and push to encrypted list - encrypted_recipients_struct.push( - Recipient { - encrypted_key: base58::encode(e_cek.as_bytes()), - header: Header { - sender: Some(base64::encode(enc_sender.as_bytes())), - kid: base64::encode(their_vk.as_bytes()) - } - }); - - } // end for-loop - }, - None => { - //anoncrypt - - } - } - - //serialize JWE struct - - //return JWE_json - serde_json::to_string(&jwe_struct) - .map_err(|err| IndyError::AgentError(AgentError::PackError(format!("Failed to serialize JWE {}", err)))) - } - - pub fn unpack_msg( - &self, - jwe_json: &str, - sender: &str, - wallet_handle: i32, - ) -> Result<(String, String)> { - - if jwe_json.contains("AuthAMES/1.0/") { //handles unpacking auth_crypt JWE - //deserialize json string to struct - let jwe_json: AuthAMES = serde_json::from_str(jwe_json).map_err(|err| { - IndyError::AgentError(AgentError::UnpackError(format!("Failed to deserialize auth ames {}", err))) - })?; - - //get recipient struct that matches sender_verkey parameter - let recipient_struct = - self.agent_service.get_auth_recipient_header(sender, jwe_json.recipients)?; - - //get key to use for decryption - let my_key: &Key = &self.wallet_service.get_indy_object(wallet_handle, sender, &RecordOptions::id_value())?; - - //decrypt recipient header - let (ephem_sym_key, sender_vk) = self.crypto_service.auth_decrypt_recipient(my_key, recipient_struct)?; - - // decode - let message = self.crypto_service.decrypt_ciphertext( - &jwe_json.ciphertext, - &jwe_json.iv, - &ephem_sym_key, - )?; - - //TODO convert this to a json_string instead of Tuple - Ok((message, sender_vk)) - - } else if jwe_json.contains("AnonAMES/1.0/") { //handles unpacking anon_crypt JWE - //deserialize json string to struct - let jwe_json: AnonAMES = serde_json::from_str(jwe_json).map_err(|err| { - IndyError::AgentError(AgentError::UnpackError(format!("Failed to deserialize auth ames {}", err))) - })?; - - //get recipient struct that matches sender_verkey parameter - let recipient_struct = - self.agent_service.get_anon_recipient_header(sender, jwe_json.recipients)?; - - //get key to use for decryption - let my_key: &Key = &self.wallet_service - .get_indy_object(wallet_handle, sender, &RecordOptions::id_value()) - .map_err(|err| IndyError::AgentError(AgentError::UnpackError(format!("Can't find my_key: {:?}", err))))?; - - //decrypt recipient header - let ephem_sym_key = self.crypto_service.anon_decrypt_recipient(my_key, recipient_struct)?; - - //decrypt message - let message = self.crypto_service.decrypt_ciphertext( - &jwe_json.ciphertext, - &jwe_json.iv, - &ephem_sym_key, - )?; - - //TODO convert this to a json_string instead of Tuple - Ok((message, "".to_string())) - - } else { - Err(IndyError::AgentError(AgentError::UnpackError(format!("Failed to unpack - unidentified ver provided")))) - } - } -} - -#[cfg(test)] -mod tests { - use domain::agent::{FromAddress, ToAddress}; - use serde_json; - use serde_json::Error; - - #[test] - pub fn test_serde_json_works() { - let sender = r#"{ wallet_key: ["pubkey12345", wallet_handle: 1] }"#; - let receivers = r#"["pubkey_1", "pubkey2", "pubkey3"]"#; - - let from_address : Result = serde_json::from_str(sender); - let to_address : Result = serde_json::from_str(receivers); - - assert!(from_address.is_ok()); - assert!(to_address.is_ok()); - } - - #[test] - pub fn test_serde_json_to_string_works() { - let sender = r#"{ wallet_key: { ["pubkey12345", wallet_handle: 1] } }"#; - let receivers = r#"["pubkey_1", "pubkey2", "pubkey3"]"#; - - let from_address : Result = serde_json::from_str(sender); - let to_address : Result = serde_json::from_str(receivers); - - assert!(from_address.is_ok()); - assert!(to_address.is_ok()); - } -} \ No newline at end of file diff --git a/libindy/src/commands/anoncreds/issuer.rs b/libindy/src/commands/anoncreds/issuer.rs index 4e91965b8f..7e9eac4d30 100644 --- a/libindy/src/commands/anoncreds/issuer.rs +++ b/libindy/src/commands/anoncreds/issuer.rs @@ -23,7 +23,7 @@ use self::indy_crypto::cl::{ }; use super::tails::{SDKTailsAccessor, store_tails_from_generator}; -use domain::anoncreds::schema::{Schema, SchemaV1, AttributeNames}; +use domain::anoncreds::schema::{Schema, SchemaV1, AttributeNames, MAX_ATTRIBUTES_COUNT}; use domain::anoncreds::credential_definition::{ CredentialDefinition, CredentialDefinitionV1, @@ -219,6 +219,12 @@ impl IssuerCommandExecutor { self.crypto_service.validate_did(issuer_did)?; + if attrs.len() > MAX_ATTRIBUTES_COUNT { + return Err(IndyError::CommonError( + CommonError::InvalidStructure( + format!("The number of Schema attributes {} cannot be greater than {}", attrs.len(), MAX_ATTRIBUTES_COUNT)))); + } + let schema_id = Schema::schema_id(issuer_did, name, version); let schema = Schema::SchemaV1(SchemaV1 { diff --git a/libindy/src/commands/crypto.rs b/libindy/src/commands/crypto.rs index 6428f5ef6f..2834267aee 100644 --- a/libindy/src/commands/crypto.rs +++ b/libindy/src/commands/crypto.rs @@ -3,61 +3,87 @@ extern crate serde_json; use std::collections::HashMap; +use domain::crypto::key::{Key, KeyInfo, KeyMetadata}; +use domain::crypto::pack::*; +use errors::common::CommonError; use errors::indy::IndyError; -use domain::crypto::key::{KeyInfo, Key, KeyMetadata}; -use services::wallet::{WalletService, RecordOptions}; +use errors::wallet::WalletError; use services::crypto::CryptoService; +use services::wallet::{RecordOptions, WalletService}; use std::rc::Rc; -use std::str; use std::result; +use std::str; +use utils::crypto::base64; +use utils::crypto::chacha20poly1305_ietf; type Result = result::Result; pub enum CryptoCommand { CreateKey( - i32, // wallet handle + i32, // wallet handle KeyInfo, // key info - Box) + Send>), + Box) + Send>, + ), SetKeyMetadata( - i32, // wallet handle + i32, // wallet handle String, // verkey String, // metadata - Box) + Send>), + Box) + Send>, + ), GetKeyMetadata( - i32, // wallet handle + i32, // wallet handle String, // verkey - Box) + Send>), + Box) + Send>, + ), CryptoSign( - i32, // wallet handle - String, // my vk + i32, // wallet handle + String, // my vk Vec, // msg - Box>) + Send>), + Box>) + Send>, + ), CryptoVerify( - String, // their vk + String, // their vk Vec, // msg Vec, // signature - Box) + Send>), + Box) + Send>, + ), AuthenticatedEncrypt( - i32, // wallet handle - String, // my vk - String, // their vk + i32, // wallet handle + String, // my vk + String, // their vk Vec, // msg - Box>) + Send>), + Box>) + Send>, + ), AuthenticatedDecrypt( - i32, // wallet handle - String, // my vk + i32, // wallet handle + String, // my vk Vec, // encrypted msg - Box)>) + Send>), + Box)>) + Send>, + ), AnonymousEncrypt( - String, // their vk + String, // their vk Vec, // msg - Box>) + Send>), + Box>) + Send>, + ), AnonymousDecrypt( - i32, // wallet handle - String, // my vk + i32, // wallet handle + String, // my vk Vec, // msg - Box>) + Send>) + Box>) + Send>, + ), + PackMessage( + Vec, // plaintext message + String, // list of receiver's keys + String, // senders verkey + i32, //wallet handle + Box>) + Send>, + ), + UnpackMessage( + Vec, // JWE + i32, // wallet handle + Box>) + Send>, + ), } pub struct CryptoCommandExecutor { @@ -66,8 +92,9 @@ pub struct CryptoCommandExecutor { } impl CryptoCommandExecutor { - pub fn new(wallet_service: Rc, - crypto_service: Rc, + pub fn new( + wallet_service: Rc, + crypto_service: Rc, ) -> CryptoCommandExecutor { CryptoCommandExecutor { wallet_service, @@ -113,29 +140,46 @@ impl CryptoCommandExecutor { info!("AnonymousDecrypt command received"); cb(self.anonymous_decrypt(wallet_handle, &my_vk, &encrypted_msg)); } + CryptoCommand::PackMessage(message, receivers, sender_vk, wallet_handle, cb) => { + info!("PackMessage command received"); + cb(self.pack_msg(message, &receivers, &sender_vk, wallet_handle)); + } + CryptoCommand::UnpackMessage(jwe_json, wallet_handle, cb) => { + info!("UnpackMessage command received"); + cb(self.unpack_msg(jwe_json, wallet_handle)); + } }; } fn create_key(&self, wallet_handle: i32, key_info: &KeyInfo) -> Result { - debug!("create_key >>> wallet_handle: {:?}, key_info: {:?}", wallet_handle, secret!(key_info)); + debug!( + "create_key >>> wallet_handle: {:?}, key_info: {:?}", + wallet_handle, + secret!(key_info) + ); let key = self.crypto_service.create_key(key_info)?; - self.wallet_service.add_indy_object(wallet_handle, &key.verkey, &key, &HashMap::new())?; + self.wallet_service + .add_indy_object(wallet_handle, &key.verkey, &key, &HashMap::new())?; let res = key.verkey; debug!("create_key <<< res: {:?}", res); Ok(res) } - fn crypto_sign(&self, - wallet_handle: i32, - my_vk: &str, - msg: &[u8]) -> Result> { - debug!("crypto_sign >>> wallet_handle: {:?}, sender_vk: {:?}, msg: {:?}", wallet_handle, my_vk, msg); + fn crypto_sign(&self, wallet_handle: i32, my_vk: &str, msg: &[u8]) -> Result> { + debug!( + "crypto_sign >>> wallet_handle: {:?}, sender_vk: {:?}, msg: {:?}", + wallet_handle, my_vk, msg + ); self.crypto_service.validate_key(my_vk)?; - let key: Key = self.wallet_service.get_indy_object(wallet_handle, &my_vk, &RecordOptions::id_value())?; + let key: Key = self.wallet_service.get_indy_object( + wallet_handle, + &my_vk, + &RecordOptions::id_value(), + )?; let res = self.crypto_service.sign(&key, msg)?; @@ -144,11 +188,11 @@ impl CryptoCommandExecutor { Ok(res) } - fn crypto_verify(&self, - their_vk: &str, - msg: &[u8], - signature: &[u8]) -> Result { - debug!("crypto_verify >>> their_vk: {:?}, msg: {:?}, signature: {:?}", their_vk, msg, signature); + fn crypto_verify(&self, their_vk: &str, msg: &[u8], signature: &[u8]) -> Result { + debug!( + "crypto_verify >>> their_vk: {:?}, msg: {:?}, signature: {:?}", + their_vk, msg, signature + ); self.crypto_service.validate_key(their_vk)?; @@ -159,34 +203,54 @@ impl CryptoCommandExecutor { Ok(res) } - fn authenticated_encrypt(&self, - wallet_handle: i32, - my_vk: &str, - their_vk: &str, - msg: &[u8]) -> Result> { - debug!("authenticated_encrypt >>> wallet_handle: {:?}, my_vk: {:?}, their_vk: {:?}, msg: {:?}", wallet_handle, my_vk, their_vk, msg); + fn authenticated_encrypt( + &self, + wallet_handle: i32, + my_vk: &str, + their_vk: &str, + msg: &[u8], + ) -> Result> { + debug!( + "authenticated_encrypt >>> wallet_handle: {:?}, my_vk: {:?}, their_vk: {:?}, msg: {:?}", + wallet_handle, my_vk, their_vk, msg + ); self.crypto_service.validate_key(my_vk)?; self.crypto_service.validate_key(their_vk)?; - let my_key: Key = self.wallet_service.get_indy_object(wallet_handle, my_vk, &RecordOptions::id_value())?; + let my_key: Key = self.wallet_service.get_indy_object( + wallet_handle, + my_vk, + &RecordOptions::id_value(), + )?; - let res = self.crypto_service.authenticated_encrypt(&my_key, their_vk, msg)?; + let res = self + .crypto_service + .authenticated_encrypt(&my_key, their_vk, msg)?; debug!("authenticated_encrypt <<< res: {:?}", res); Ok(res) } - fn authenticated_decrypt(&self, - wallet_handle: i32, - my_vk: &str, - msg: &[u8]) -> Result<(String, Vec)> { - debug!("authenticated_decrypt >>> wallet_handle: {:?}, my_vk: {:?}, msg: {:?}", wallet_handle, my_vk, msg); + fn authenticated_decrypt( + &self, + wallet_handle: i32, + my_vk: &str, + msg: &[u8], + ) -> Result<(String, Vec)> { + debug!( + "authenticated_decrypt >>> wallet_handle: {:?}, my_vk: {:?}, msg: {:?}", + wallet_handle, my_vk, msg + ); self.crypto_service.validate_key(my_vk)?; - let my_key: Key = self.wallet_service.get_indy_object(wallet_handle, my_vk, &RecordOptions::id_value())?; + let my_key: Key = self.wallet_service.get_indy_object( + wallet_handle, + my_vk, + &RecordOptions::id_value(), + )?; let res = self.crypto_service.authenticated_decrypt(&my_key, &msg)?; @@ -195,10 +259,11 @@ impl CryptoCommandExecutor { Ok(res) } - fn anonymous_encrypt(&self, - their_vk: &str, - msg: &[u8]) -> Result> { - debug!("anonymous_encrypt >>> their_vk: {:?}, msg: {:?}", their_vk, msg); + fn anonymous_encrypt(&self, their_vk: &str, msg: &[u8]) -> Result> { + debug!( + "anonymous_encrypt >>> their_vk: {:?}, msg: {:?}", + their_vk, msg + ); self.crypto_service.validate_key(their_vk)?; @@ -209,17 +274,28 @@ impl CryptoCommandExecutor { Ok(res) } - fn anonymous_decrypt(&self, - wallet_handle: i32, - my_vk: &str, - encrypted_msg: &[u8]) -> Result> { - debug!("anonymous_decrypt >>> wallet_handle: {:?}, my_vk: {:?}, encrypted_msg: {:?}", wallet_handle, my_vk, encrypted_msg); + fn anonymous_decrypt( + &self, + wallet_handle: i32, + my_vk: &str, + encrypted_msg: &[u8], + ) -> Result> { + debug!( + "anonymous_decrypt >>> wallet_handle: {:?}, my_vk: {:?}, encrypted_msg: {:?}", + wallet_handle, my_vk, encrypted_msg + ); self.crypto_service.validate_key(&my_vk)?; - let my_key: Key = self.wallet_service.get_indy_object(wallet_handle, &my_vk, &RecordOptions::id_value())?; + let my_key: Key = self.wallet_service.get_indy_object( + wallet_handle, + &my_vk, + &RecordOptions::id_value(), + )?; - let res = self.crypto_service.crypto_box_seal_open(&my_key, &encrypted_msg)?; + let res = self + .crypto_service + .crypto_box_seal_open(&my_key, &encrypted_msg)?; debug!("anonymous_decrypt <<< res: {:?}", res); @@ -227,27 +303,38 @@ impl CryptoCommandExecutor { } fn set_key_metadata(&self, wallet_handle: i32, verkey: &str, metadata: &str) -> Result<()> { - debug!("set_key_metadata >>> wallet_handle: {:?}, verkey: {:?}, metadata: {:?}", wallet_handle, verkey, metadata); + debug!( + "set_key_metadata >>> wallet_handle: {:?}, verkey: {:?}, metadata: {:?}", + wallet_handle, verkey, metadata + ); self.crypto_service.validate_key(verkey)?; - let metadata = KeyMetadata {value: metadata.to_string()}; + let metadata = KeyMetadata { + value: metadata.to_string(), + }; - self.wallet_service.upsert_indy_object(wallet_handle, &verkey, &metadata)?; + self.wallet_service + .upsert_indy_object(wallet_handle, &verkey, &metadata)?; debug!("set_key_metadata <<<"); Ok(()) } - fn get_key_metadata(&self, - wallet_handle: i32, - verkey: &str) -> Result { - debug!("get_key_metadata >>> wallet_handle: {:?}, verkey: {:?}", wallet_handle, verkey); + fn get_key_metadata(&self, wallet_handle: i32, verkey: &str) -> Result { + debug!( + "get_key_metadata >>> wallet_handle: {:?}, verkey: {:?}", + wallet_handle, verkey + ); self.crypto_service.validate_key(verkey)?; - let metadata = self.wallet_service.get_indy_object::(wallet_handle, &verkey, &RecordOptions::id_value())?; + let metadata = self.wallet_service.get_indy_object::( + wallet_handle, + &verkey, + &RecordOptions::id_value(), + )?; let res = metadata.value; @@ -255,4 +342,261 @@ impl CryptoCommandExecutor { Ok(res) } + + //TODO: Refactor pack to be more modular to version changes or crypto_scheme changes + //this match statement is super messy, but the easiest way to comply with current architecture + pub fn pack_msg( + &self, + message: Vec, + receivers: &str, + sender_vk: &str, + wallet_handle: i32, + ) -> Result> { + //generate cek + let cek = chacha20poly1305_ietf::gen_key(); + + //list of ceks used to construct JWE later + let mut encrypted_recipients_struct: Vec = vec![]; + + //parse receivers to structs + let receiver_list: Vec = serde_json::from_str(receivers).map_err(|err| { + IndyError::CommonError(CommonError::InvalidStructure(format!( + "Failed to deserialize receiver list of keys {}", + err + ))) + })?; + + //break early and error out if no receivers keys are provided + if receiver_list.is_empty() { + return Err(IndyError::CommonError(CommonError::InvalidParam4(format!( + "No receiver keys found" + )))); + } + + match sender_vk.is_empty() { + true => { + // anoncrypt + //encrypt cek for recipient + for their_vk in receiver_list { + //encrypt sender verkey + let enc_cek = self.crypto_service.crypto_box_seal(&their_vk, &cek[..])?; + + //create recipient struct and push to encrypted list + encrypted_recipients_struct.push(Recipient { + encrypted_key: base64::encode(enc_cek.as_slice()), + header: Header { + kid: their_vk, + }, + }); + } // end for-loop + + self._format_pack_message(encrypted_recipients_struct, message, &cek, false) + } + false => { + //authcrypt + //get my_key from my wallet + let my_key = self.wallet_service.get_indy_object( + wallet_handle, + sender_vk, + &RecordOptions::id_value() + )?; + + //encrypt cek for recipient + for their_vk in receiver_list { + let enc_cek = + self.crypto_service + .authenticated_encrypt(&my_key, &their_vk, &cek[..])?; + + //create recipient struct and push to encrypted list + encrypted_recipients_struct.push(Recipient { + encrypted_key: base64::encode(enc_cek.as_slice()), + header: Header { + kid:their_vk, + }, + }); + } // end for-loop + + self._format_pack_message(encrypted_recipients_struct, message, &cek, true) + } + } + } + + pub fn unpack_msg(&self, jwe_json: Vec, wallet_handle: i32) -> Result> { + //serialize JWE to struct + let jwe_struct: JWE = serde_json::from_slice(jwe_json.as_slice()).map_err(|err| { + IndyError::CommonError(CommonError::InvalidStructure(format!( + "Failed to deserialize auth ames {}", + err + ))) + })?; + + + //decode protected data + let protected_decoded_vec = base64::decode(&jwe_struct.protected)?; + let protected_decoded_str = String::from_utf8(protected_decoded_vec).map_err(|err| { + IndyError::CommonError(CommonError::InvalidStructure(format!( + "Failed to utf8 encode data {}", + err + ))) + })?; + + //convert protected_data_str to struct + let protected_struct: Protected = + serde_json::from_str(&protected_decoded_str).map_err(|err| { + IndyError::CommonError(CommonError::InvalidStructure(format!( + "Failed to deserialize protected data {}", + err + ))) + })?; + + //search through recipients_list and check if one of the kid matches a verkey in the wallet + for recipient in protected_struct.recipients { + + let my_key_res = self.wallet_service.get_indy_object( + wallet_handle, + &recipient.header.kid, + &RecordOptions::id_value() + ).map_err(|err| IndyError::WalletError(err)); + + + if my_key_res.is_ok() { + //TODO change to move this to a separate function and return recipient rather than putting logic inside the for loop. + // For loops have no way to return values in rust + + //decode encrypted_key + let encrypted_key_vec = base64::decode(&recipient.encrypted_key)?; + + //get cek and sender data + let (sender_verkey, cek) = + match protected_struct.alg.as_ref() { + "Authcrypt" => { + + //get my key based on kid + let my_key = my_key_res.unwrap(); + + //decrypt cek + let (sender_vk, cek_as_vec) = self + .crypto_service + .authenticated_decrypt(&my_key, encrypted_key_vec.as_slice())?; + + //convert to chacha Key struct + let cek: chacha20poly1305_ietf::Key = + chacha20poly1305_ietf::Key::from_slice(&cek_as_vec[..]).map_err( + |err| { + IndyError::CommonError(CommonError::InvalidStructure( + format!("Failed to decrypt cek {}", err), + )) + }, + )?; + + Ok((Some(sender_vk), cek)) + } //close authcrypt option + + "Anoncrypt" => { + //get my private key + let my_key = self.wallet_service.get_indy_object( + wallet_handle, + &recipient.header.kid, + &RecordOptions::id_value(), + )?; + + //decrypt cek + let cek_as_vec = self + .crypto_service + .crypto_box_seal_open(&my_key, encrypted_key_vec.as_slice())?; + + //convert to chacha Key struct + let cek: chacha20poly1305_ietf::Key = + chacha20poly1305_ietf::Key::from_slice(&cek_as_vec[..]).map_err( + |err| { + IndyError::CommonError(CommonError::InvalidStructure( + format!("Failed to decrypt cek {}", err), + )) + }, + )?; + + Ok((None, cek)) + } //close Anoncrypt option + + _ => Err(IndyError::CommonError(CommonError::InvalidStructure( + format!("Failed to deserialize cek encryption alg"), + ))), + }?; //close cek and sender_data match statement + + let message = self.crypto_service.decrypt_ciphertext( + &jwe_struct.ciphertext, + &jwe_struct.protected, + &jwe_struct.iv, + &jwe_struct.tag, + &cek, + )?; + + let res = UnpackMessage { + message, + sender_verkey, + }; + + return serde_json::to_vec(&res).map_err(|err| { + IndyError::CommonError(CommonError::InvalidStructure(format!( + "Failed to serialize message {}", + err + ))) + }); + } // close if statement if a kid matches a verkey found in wallet + } // close for loop searching through recipients on kid + + // If it gets to this point no verkey was found in wallet that matches a kid so return Error + return Err(IndyError::WalletError(WalletError::ItemNotFound)); + } + + fn _format_pack_message( + &self, + encrypted_recipients_struct: Vec, + message: Vec, + cek: &chacha20poly1305_ietf::Key, + alg_is_authcrypt: bool + ) -> Result> { + + let alg_val= match alg_is_authcrypt { + true => String::from("Authcrypt"), + false => String::from("Anoncrypt") + }; + + //structure protected and base64URL encode it + let protected_struct = Protected { + enc: "xchacha20poly1305".to_string(), + typ: "JWM/1.0".to_string(), + alg: alg_val, + recipients: encrypted_recipients_struct, + }; + let protected_encoded = serde_json::to_string(&protected_struct).map_err(|err| { + IndyError::CommonError(CommonError::InvalidStructure(format!( + "Failed to serialize protected field {}", + err + ))) + })?; + + let base64_protected = base64::encode(protected_encoded.as_bytes()); + + // encrypt ciphertext and integrity protect "protected" field + let (ciphertext, iv, tag) = + self.crypto_service + .encrypt_plaintext(message, &base64_protected, cek); + + //construct JWE struct + let jwe_struct = JWE { + protected: base64_protected, + iv, + ciphertext, + tag, + }; + + //convert JWE struct to a string and return + serde_json::to_vec(&jwe_struct).map_err(|err| { + IndyError::CommonError(CommonError::InvalidStructure(format!( + "Failed to serialize JWE {}", + err + ))) + }) + } } diff --git a/libindy/src/commands/mod.rs b/libindy/src/commands/mod.rs index 060f906a2e..571ae3629a 100644 --- a/libindy/src/commands/mod.rs +++ b/libindy/src/commands/mod.rs @@ -8,7 +8,6 @@ pub mod wallet; pub mod pairwise; pub mod non_secrets; pub mod payments; -pub mod agent; extern crate indy_crypto; extern crate threadpool; @@ -25,7 +24,6 @@ use commands::wallet::{WalletCommand, WalletCommandExecutor}; use commands::pairwise::{PairwiseCommand, PairwiseCommandExecutor}; use commands::non_secrets::{NonSecretsCommand, NonSecretsCommandExecutor}; use commands::payments::{PaymentsCommand, PaymentsCommandExecutor}; -// use commands::agent::{AgentCommand, AgentCommandExecutor}; use errors::common::CommonError; @@ -36,7 +34,6 @@ use services::pool::PoolService; use services::wallet::WalletService; use services::crypto::CryptoService; use services::ledger::LedgerService; -use services::agent::AgentService; use domain::IndyConfig; @@ -59,7 +56,6 @@ pub enum Command { Pairwise(PairwiseCommand), NonSecrets(NonSecretsCommand), Payments(PaymentsCommand), - //Agent(AgentCommand) } lazy_static! { @@ -100,7 +96,6 @@ impl CommandExecutor { let payments_service = Rc::new(PaymentsService::new()); let pool_service = Rc::new(PoolService::new()); let wallet_service = Rc::new(WalletService::new()); - //let agent_service = Rc::new(AgentService::new()); let anoncreds_command_executor = AnoncredsCommandExecutor::new(anoncreds_service.clone(), blob_storage_service.clone(), pool_service.clone(), wallet_service.clone(), crypto_service.clone()); let crypto_command_executor = CryptoCommandExecutor::new(wallet_service.clone(), crypto_service.clone()); @@ -112,7 +107,6 @@ impl CommandExecutor { let blob_storage_command_executor = BlobStorageCommandExecutor::new(blob_storage_service.clone()); let non_secret_command_executor = NonSecretsCommandExecutor::new(wallet_service.clone()); let payments_command_executor = PaymentsCommandExecutor::new(payments_service.clone(), wallet_service.clone(), crypto_service.clone()); - //let agent_command_executor = AgentCommandExecutor::new(wallet_service.clone(), crypto_service.clone(), agent_service.clone()); loop { match receiver.recv() { @@ -156,10 +150,6 @@ impl CommandExecutor { info!("PaymentsCommand command received"); payments_command_executor.execute(cmd); } -// Ok(Command::Agent(cmd)) => { -// info!("AgentCommand command received"); -// agent_command_executor.execute(cmd); -// } Ok(Command::Exit) => { info!("Exit command received"); break diff --git a/libindy/src/commands/route.rs b/libindy/src/commands/route.rs index c31a462b01..cdabd1079a 100644 --- a/libindy/src/commands/route.rs +++ b/libindy/src/commands/route.rs @@ -78,7 +78,7 @@ impl RouteCommandExecutor { })?; //encrypt ciphertext - let (sym_key, iv, ciphertext) = self.crypto_service.encrypt_ciphertext(message); + let (cek, iv, ciphertext) = self.crypto_service.encrypt_ciphertext(message); //convert sender_vk to Key let my_key = &ws @@ -90,7 +90,7 @@ impl RouteCommandExecutor { for their_vk in recv_keys { auth_recipients.push( - self.auth_encrypt_recipient(my_key, their_vk, &sym_key, cs.clone()) + self.auth_encrypt_recipient(my_key, their_vk, &cek, cs.clone()) .map_err(|err| { RouteError::PackError(format!("Failed to push auth recipient {}", err)) })?, @@ -116,13 +116,13 @@ impl RouteCommandExecutor { })?; //encrypt ciphertext - let (sym_key, iv, ciphertext) = self.encrypt_ciphertext(message); + let (cek, iv, ciphertext) = self.encrypt_ciphertext(message); //encrypt ceks let mut anon_recipients: Vec = vec![]; for their_vk in recv_keys { let anon_recipient = - self.anon_encrypt_recipient(their_vk, sym_key.clone(), cs.clone())?; + self.anon_encrypt_recipient(their_vk, cek.clone(), cs.clone())?; anon_recipients.push(anon_recipient); } @@ -162,14 +162,14 @@ impl RouteCommandExecutor { .map_err(|err| RouteError::UnpackError(format!("Can't find my_key: {:?}", err)))?; //decrypt recipient header - let (ephem_sym_key, sender_vk) = + let (ephem_cek, sender_vk) = self.crypto_service.auth_decrypt_recipient(my_key, recipient_struct)?; // decode let message = self.crypto_service.decrypt_ciphertext( &auth_ames_struct.ciphertext, &auth_ames_struct.iv, - &ephem_sym_key, + &ephem_cek, )?; Ok((message, sender_vk)) @@ -191,13 +191,13 @@ impl RouteCommandExecutor { .map_err(|err| RouteError::UnpackError(format!("Can't find my_key: {:?}", err)))?; //decrypt recipient header - let ephem_sym_key = self.crypto_service.anon_decrypt_recipient(my_key, recipient_struct)?; + let ephem_cek = self.crypto_service.anon_decrypt_recipient(my_key, recipient_struct)?; //decrypt message let message = self.crypto_service.decrypt_ciphertext( &auth_ames_struct.ciphertext, &auth_ames_struct.iv, - &ephem_sym_key, + &ephem_cek, )?; //return message and no key diff --git a/libindy/src/domain/agent/mod.rs b/libindy/src/domain/agent/mod.rs deleted file mode 100644 index 2bcc63a91e..0000000000 --- a/libindy/src/domain/agent/mod.rs +++ /dev/null @@ -1,86 +0,0 @@ -#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] -pub struct AuthRecipient { - pub enc_from : String, - pub e_cek: String, - pub cek_nonce: String, - pub to : String -} - -#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] -pub struct AnonRecipient { - pub cek: String, - pub to: String -} - -#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] -pub struct AuthAMES { - pub recipients: Vec, - pub ver: String, - pub enc: String, - pub ciphertext: String, - pub iv: String -} - -#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] -pub struct AnonAMES { - pub recipients: Vec, - pub ver: String, - pub enc: String, - pub ciphertext: String, - pub iv: String -} - -#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] -pub enum AMES { - Auth(AuthAMES), - Anon(AnonAMES) -} - -#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] -pub struct JWE { - pub protected: Protected, - pub recipients: Vec, - pub aad: String, - pub iv: String, - pub ciphertext: String, - pub tag: String - -} - -#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] -pub struct Recipient { - pub encrypted_key: String, - pub header: Header -} - - -#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] -pub struct Header { - pub sender: Option, - pub kid: String -} - -#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] -pub struct Protected { - pub enc: String, - pub typ: String, - pub aad_hash_alg: String, - pub cek_enc: String -} - -#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] -pub struct FromAddress { - wallet_key: WalletKey -} - -#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] -#[serde(untagged)] -pub enum WalletKey { - WalletKeyId(i32, String) //wallet_handle, base58 encoded public key -} - -#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] -#[serde(untagged)] -pub enum ToAddress { - public_key(Vec) -} \ No newline at end of file diff --git a/libindy/src/domain/anoncreds/schema.rs b/libindy/src/domain/anoncreds/schema.rs index a2588b248f..7b453338bc 100644 --- a/libindy/src/domain/anoncreds/schema.rs +++ b/libindy/src/domain/anoncreds/schema.rs @@ -3,6 +3,7 @@ use super::DELIMITER; use std::collections::{HashMap, HashSet}; pub const SCHEMA_MARKER: &'static str = "2"; +pub const MAX_ATTRIBUTES_COUNT: usize = 125; #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "camelCase")] diff --git a/libindy/src/domain/crypto/mod.rs b/libindy/src/domain/crypto/mod.rs index 9d63af2ef9..13bb318baa 100644 --- a/libindy/src/domain/crypto/mod.rs +++ b/libindy/src/domain/crypto/mod.rs @@ -1,3 +1,4 @@ pub mod key; pub mod did; pub mod combo_box; +pub mod pack; diff --git a/libindy/src/domain/crypto/pack.rs b/libindy/src/domain/crypto/pack.rs new file mode 100644 index 0000000000..e20bc666ed --- /dev/null +++ b/libindy/src/domain/crypto/pack.rs @@ -0,0 +1,35 @@ +#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] +pub struct JWE { + pub protected: String, + pub iv: String, + pub ciphertext: String, + pub tag: String + +} + +#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] +pub struct Recipient { + pub encrypted_key: String, + pub header: Header +} + + +#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] +pub struct Header { + pub kid: String +} + +#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] +pub struct Protected { + pub enc: String, + pub typ: String, + pub alg: String, + pub recipients: Vec, +} + +#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] +pub struct UnpackMessage { + pub message: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub sender_verkey: Option +} \ No newline at end of file diff --git a/libindy/src/domain/mod.rs b/libindy/src/domain/mod.rs index 013794691d..0ed46eb7e0 100644 --- a/libindy/src/domain/mod.rs +++ b/libindy/src/domain/mod.rs @@ -4,7 +4,6 @@ pub mod ledger; pub mod pairwise; pub mod pool; pub mod wallet; -pub mod agent; #[derive(Debug, Serialize, Deserialize)] pub struct IndyConfig { diff --git a/libindy/src/errors/agent.rs b/libindy/src/errors/agent.rs deleted file mode 100644 index 7eb437e51d..0000000000 --- a/libindy/src/errors/agent.rs +++ /dev/null @@ -1,58 +0,0 @@ -use api::ErrorCode; -use errors::ToErrorCode; - -use std::error; -use std::fmt; - -use errors::common::CommonError; - -#[derive(Debug)] -pub enum AgentError { - UnpackError(String), - PackError(String), - CommonError(CommonError) -} - -impl fmt::Display for AgentError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - AgentError::UnpackError(ref description) => write!(f, "Failed while unpacking message: {}", description), - AgentError::PackError(ref description) => write!(f, "Failed while packing message: {}", description), - AgentError::CommonError(ref err) => err.fmt(f) - } - } -} - -impl error::Error for AgentError { - fn description(&self) -> &str { - match *self { - AgentError::UnpackError(ref description) => description, - AgentError::PackError(ref description) => description, - AgentError::CommonError(ref err) => err.description() - } - } - - fn cause(&self) -> Option<&error::Error> { - match *self { - AgentError::UnpackError(_) => None, - AgentError::PackError(_) => None, - AgentError::CommonError(ref err) => Some(err) - } - } -} - -impl ToErrorCode for AgentError { - fn to_error_code(&self) -> ErrorCode { - match *self { - AgentError::UnpackError(_) => ErrorCode::RouteUnpackError, - AgentError::PackError(_) => ErrorCode::RoutePackError, - AgentError::CommonError(ref err) => err.to_error_code() - } - } -} - -impl From for AgentError { - fn from(err: CommonError) -> AgentError { - AgentError::CommonError(err) - } -} \ No newline at end of file diff --git a/libindy/src/errors/indy.rs b/libindy/src/errors/indy.rs index 881e7f69fa..85802bdae6 100644 --- a/libindy/src/errors/indy.rs +++ b/libindy/src/errors/indy.rs @@ -6,7 +6,6 @@ use errors::crypto::CryptoError; use errors::wallet::WalletError; use errors::did::DidError; use errors::payments::PaymentsError; -use errors::agent::AgentError; use api::ErrorCode; use errors::ToErrorCode; @@ -24,7 +23,6 @@ pub enum IndyError { WalletError(WalletError), DidError(DidError), PaymentsError(PaymentsError), - AgentError(AgentError) } impl fmt::Display for IndyError { @@ -38,7 +36,6 @@ impl fmt::Display for IndyError { IndyError::WalletError(ref err) => err.fmt(f), IndyError::DidError(ref err) => err.fmt(f), IndyError::PaymentsError(ref err) => err.fmt(f), - IndyError::AgentError(ref err) => err.fmt(f), } } } @@ -54,7 +51,6 @@ impl error::Error for IndyError { IndyError::WalletError(ref err) => err.description(), IndyError::DidError(ref err) => err.description(), IndyError::PaymentsError(ref err) => err.description(), - IndyError::AgentError(ref err) => err.description(), } } @@ -68,7 +64,6 @@ impl error::Error for IndyError { IndyError::WalletError(ref err) => Some(err), IndyError::DidError(ref err) => Some(err), IndyError::PaymentsError(ref err) => Some(err), - IndyError::AgentError(ref err) => Some(err), } } } @@ -85,7 +80,6 @@ impl ToErrorCode for IndyError { IndyError::WalletError(ref err) => err.to_error_code(), IndyError::DidError(ref err) => err.to_error_code(), IndyError::PaymentsError(ref err) => err.to_error_code(), - IndyError::AgentError(ref err) => err.to_error_code(), } } } @@ -137,9 +131,3 @@ impl From for IndyError { IndyError::PaymentsError(err) } } - -impl From for IndyError { - fn from(err : AgentError) -> IndyError { - IndyError::AgentError(err) - } -} \ No newline at end of file diff --git a/libindy/src/errors/mod.rs b/libindy/src/errors/mod.rs index 7a36013408..ce4fe1fd0b 100644 --- a/libindy/src/errors/mod.rs +++ b/libindy/src/errors/mod.rs @@ -7,7 +7,6 @@ pub mod indy; pub mod wallet; pub mod did; pub mod payments; -pub mod agent; use api::ErrorCode; diff --git a/libindy/src/services/agent/mod.rs b/libindy/src/services/agent/mod.rs deleted file mode 100644 index d8542fd54a..0000000000 --- a/libindy/src/services/agent/mod.rs +++ /dev/null @@ -1,314 +0,0 @@ -use core::result; -use domain::crypto::key::Key; -use domain::agent::*; -use errors::agent::AgentError; -use serde_json; -use services::crypto::CryptoService; -use services::wallet::{RecordOptions, WalletService}; -use std::rc::Rc; -use utils::crypto::base58; -use utils::crypto::base64; -use utils::crypto::xsalsa20; -use utils::crypto::xsalsa20::{create_key, gen_nonce}; - -type Result = result::Result; - -pub struct AgentService {} - -impl AgentService { - pub fn new() -> AgentService { - AgentService {} - } - - pub fn get_recipient_header( - &self, - recipient_verkey: &str, - recipients_list: Vec, - ) -> Result { - for recipient in recipients_list { - if &recipient.header.kid == recipient_verkey { - return Ok(recipient); - } - } - - Err(AgentError::UnpackError(format!( - "Failed to find a matching header" - ))) - } -} - -#[cfg(test)] -pub mod tests { - use super::*; - use domain::agent::{Recipient, Header}; - - #[test] - pub fn test_get_recipient_header_works(){ - let service = AgentService::new(); - - let verkey = "key_of_recipient1".to_string(); - - let recp1 : Recipient = Recipient { - encrypted_key: "unrelevant data".to_string(), - header: Header { - sender : "unrelevant for this test".to_string(), - kid : "key_of_recipient1".to_string(), - } - }; - - let recp2 : Recipient = Recipient { - encrypted_key: "unrelevant data".to_string(), - header: Header { - sender : "unrelevant for this test".to_string(), - kid : "key_of_recipient2".to_string(), - } - }; - - let test_recp_list : Vec = vec![recp1, recp2]; - - let returned_recipient = service.get_recipient_header(&verkey.clone(), test_recp_list).unwrap(); - - assert_eq!(returned_recipient.header.kid, verkey); - } - - #[test] - pub fn test_get_recipient_header_unpack_error(){ - let service = AgentService::new(); - - let verkey = "key_of_recipient1".to_string(); - - let recp1 : Recipient = Recipient { - encrypted_key: "unrelevant data".to_string(), - header: Header { - sender : "unrelevant for this test".to_string(), - kid : "key_does_not_match1".to_string(), - } - }; - - let recp2 : Recipient = Recipient { - encrypted_key: "unrelevant data".to_string(), - header: Header { - sender : "unrelevant for this test".to_string(), - kid : "key_does_not_match2".to_string(), - } - }; - - let test_recp_list : Vec = vec![recp1, recp2]; - - let returned_recipient = service.get_recipient_header(&verkey.clone(), test_recp_list); - - assert!(returned_recipient.is_err()); - } -} - -//pub mod tests { -// -// // TODO Fix texts so only one wallet is used to speed up tests -// //unit tests -// -// -// /* component test useful to identify if unpack is breaking or if pack is breaking. If unpack is -// * breaking both this test and the tests below will fail. If only pack is breaking, only this test -// * will fail. -// */ -// -// // Integration tests -// -// pub fn test_single_anon_pack_message_and_unpack_msg_success() { -// _cleanup(); -// //setup generic data to test -// let expected_message = "Hello World"; -// -// //setup route_service -// let rs: Rc = Rc::new(AgentService::new()); -// let cs: Rc = Rc::new(CryptoService::new()); -// let ws: Rc = Rc::new(WalletService::new()); -// -// //setup wallets -// let (recv_wallet_handle, _, recv_key) = _setup_recv_wallet1(ws.clone(), cs.clone()); -// -// //setup recv_keys list -// let recv_verkey: &str = recv_key.verkey.as_ref(); -// let recv_keys: Vec<&str> = vec![recv_verkey]; -// -// //pack then unpack message -// let packed_msg = rs -// .anon_pack_msg(expected_message, recv_keys, cs.clone()) -// .unwrap(); -// -// let (message, _) = rs -// .unpack_msg( -// &packed_msg, -// &recv_key.verkey, -// recv_wallet_handle, -// ws.clone(), -// cs.clone(), -// ) -// .unwrap(); -// -// //verify same plaintext goes in and comes out -// assert_eq!(expected_message.to_string(), message); -// } -// -// -// pub fn test_single_auth_pack_msg_and_unpack_msg_success() { -// _cleanup(); -// //setup generic data to test -// let expected_message = "Hello World"; -// -// //setup route_service -// let rs: Rc = Rc::new(AgentService::new()); -// let cs: Rc = Rc::new(CryptoService::new()); -// let ws: Rc = Rc::new(WalletService::new()); -// -// //setup wallets -// let (recv_wallet_handle, _, recv_key) = _setup_recv_wallet1(ws.clone(), cs.clone()); -// let (send_wallet_handle, _, send_key) = _setup_send_wallet(ws.clone(), cs.clone()); -// -// //setup recv_keys list -// let recv_verkey: &str = recv_key.verkey.as_ref(); -// let recv_keys: Vec<&str> = vec![recv_verkey]; -// -// //pack then unpack message -// let packed_msg = rs -// .auth_pack_msg( -// expected_message, -// recv_keys, -// &send_key.verkey, -// send_wallet_handle, -// ws.clone(), -// cs.clone(), -// ) -// .unwrap(); -// -// let (message, sender_vk) = rs -// .unpack_msg( -// &packed_msg, -// &recv_key.verkey, -// recv_wallet_handle, -// ws.clone(), -// cs.clone(), -// ) -// .unwrap(); -// -// //verify same plaintext goes in and comes out -// assert_eq!(expected_message.to_string(), message); -// assert_eq!(sender_vk, send_key.verkey); -// } -// -// -// pub fn test_pack_and_unpack_msg_success_multi_anoncrypt() { -// _cleanup(); -// //setup generic data to test -// let plaintext = "Hello World"; -// -// //setup route_service -// let rs: Rc = Rc::new(AgentService::new()); -// let cs: Rc = Rc::new(CryptoService::new()); -// let ws: Rc = Rc::new(WalletService::new()); -// -// //setup recv_keys to use with pack_msg -// let (_, recv_key1_before_wallet_setup) = _recv_did1(cs.clone()); -// let (_, recv_key2_before_wallet_setup) = _recv_did2(cs.clone()); -// let recv_keys = vec![ -// recv_key1_before_wallet_setup.verkey.as_ref(), -// recv_key2_before_wallet_setup.verkey.as_ref(), -// ]; -// -// //setup send wallet then pack message -// let (send_wallet_handle, _, _) = _setup_send_wallet(ws.clone(), cs.clone()); -// let packed_msg = rs.anon_pack_msg(plaintext, recv_keys, cs.clone()).unwrap(); -// let _result1 = ws.close_wallet(send_wallet_handle); -// -// //setup recv_wallet1 and unpack message then verify plaintext -// let (recv_wallet_handle1, _, recv_key1) = _setup_recv_wallet1(ws.clone(), cs.clone()); -// let (unpacked_msg1, _) = rs -// .unpack_msg( -// &packed_msg, -// &recv_key1.verkey, -// recv_wallet_handle1, -// ws.clone(), -// cs.clone(), -// ) -// .unwrap(); -// -// //test first recipient -// assert_eq!(plaintext.to_string(), unpacked_msg1); -// let _result2 = ws.close_wallet(recv_wallet_handle1); -// -// //setup recv_wallet2 and unpack message then verify plaintext -// let (recv_wallet_handle2, _, recv_key2) = _setup_recv_wallet2(ws.clone(), cs.clone()); -// let (unpacked_msg2, _) = rs -// .unpack_msg( -// &packed_msg, -// &recv_key2.verkey, -// recv_wallet_handle2, -// ws.clone(), -// cs.clone(), -// ) -// .unwrap(); -// -// //test second recipient -// assert_eq!(plaintext, &unpacked_msg2); -// let _result2 = ws.close_wallet(recv_wallet_handle2); -// } -// -// -// pub fn test_pack_and_unpack_msg_success_multi_authcrypt() { -// _cleanup(); -// //setup generic data to test -// let plaintext = "Hello World"; -// -// //setup route_service -// let rs: Rc = Rc::new(AgentService::new()); -// let cs: Rc = Rc::new(CryptoService::new()); -// let ws: Rc = Rc::new(WalletService::new()); -// -// //setup recv_keys to use with pack_msg -// let (_, recv_key1_before_wallet_setup) = _recv_did1(cs.clone()); -// let (_, recv_key2_before_wallet_setup) = _recv_did2(cs.clone()); -// let recv_keys = vec![ -// recv_key1_before_wallet_setup.verkey.as_ref(), -// recv_key2_before_wallet_setup.verkey.as_ref(), -// ]; -// -// //setup send wallet then pack message -// let (send_wallet_handle, _, expected_send_key) = _setup_send_wallet(ws.clone(), cs.clone()); -// let packed_msg = rs.auth_pack_msg(plaintext, recv_keys, &expected_send_key.verkey, send_wallet_handle, ws.clone(), cs.clone()).unwrap(); -// let _result1 = ws.close_wallet(send_wallet_handle); -// -// //setup recv_wallet1 and unpack message then verify plaintext -// let (recv_wallet_handle1, _, recv_key1) = _setup_recv_wallet1(ws.clone(), cs.clone()); -// let (unpacked_msg1, send_vk_1) = rs -// .unpack_msg( -// &packed_msg, -// &recv_key1.verkey, -// recv_wallet_handle1, -// ws.clone(), -// cs.clone(), -// ) -// .unwrap(); -// -// //test first recipient -// assert_eq!(plaintext.to_string(), unpacked_msg1); -// assert_eq!(&expected_send_key.verkey, &send_vk_1); -// let _result2 = ws.close_wallet(recv_wallet_handle1); -// -// //setup recv_wallet2 and unpack message then verify plaintext -// let (recv_wallet_handle2, _, recv_key2) = _setup_recv_wallet2(ws.clone(), cs.clone()); -// let (unpacked_msg2, send_vk_2) = rs -// .unpack_msg( -// &packed_msg, -// &recv_key2.verkey, -// recv_wallet_handle2, -// ws.clone(), -// cs.clone(), -// ) -// .unwrap(); -// -// //test second recipient -// assert_eq!(plaintext, &unpacked_msg2); -// assert_eq!(&expected_send_key.verkey, &send_vk_2); -// let _result2 = ws.close_wallet(recv_wallet_handle2); -// } -//} \ No newline at end of file diff --git a/libindy/src/services/crypto/mod.rs b/libindy/src/services/crypto/mod.rs index baa8ca2f69..bada53cd5c 100644 --- a/libindy/src/services/crypto/mod.rs +++ b/libindy/src/services/crypto/mod.rs @@ -7,18 +7,16 @@ use self::hex::FromHex; use errors::common::CommonError; use errors::crypto::CryptoError; -use errors::agent::AgentError; use domain::crypto::key::{Key, KeyInfo}; use domain::crypto::did::{Did, MyDidInfo, TheirDidInfo, TheirDid}; use domain::crypto::combo_box::ComboBox; -use domain::agent::Recipient; use utils::crypto::base58; use utils::crypto::base64; use utils::crypto::verkey_builder::build_full_verkey; use utils::crypto::ed25519_sign; use utils::crypto::ed25519_box; use utils::crypto::chacha20poly1305_ietf; -use utils::crypto::chacha20poly1305_ietf::{gen_key, gen_nonce_and_encrypt}; +use utils::crypto::chacha20poly1305_ietf::{ gen_nonce_and_encrypt_detached}; use std::collections::HashMap; use std::str; @@ -451,136 +449,42 @@ impl CryptoService { Ok(res) } -// /* Authcrypt helper function section */ -// pub fn anon_encrypt_recipient( -// &self, -// recp_vk: &str, -// sym_key: chacha20poly1305_ietf::Key -// ) -> Result { -// //encrypt cek -// let cek = self.crypto_box_seal(recp_vk, &sym_key[..]).map_err(|err| { -// CryptoError::UnknownCryptoError(format!("Failed to encrypt anon recipient {}", err)) -// })?; -// -// //generate struct -// let anon_recipient = AnonRecipient { -// to: recp_vk.to_string(), -// cek: base64::encode(cek.as_slice()), -// }; -// -// Ok(anon_recipient) -// } -// -// pub fn anon_decrypt_recipient( -// &self, -// my_key: &Key, -// recipient: &Recipient -// ) -> Result { -// let cek_as_vec = base64::decode(&anon_recipient.cek).map_err(|err| { -// CryptoError::CommonError( -// CommonError::InvalidStructure(format!("Failed to decode cek for anon_decrypt_recipient {}", err)) -// ) -// })?; -// let cek_as_bytes = cek_as_vec.as_ref(); -// -// let decrypted_cek = self -// .crypto_box_seal_open(my_key, cek_as_bytes) -// .map_err(|err| CryptoError::UnknownCryptoError(format!("Failed to decrypt cek {}", err)))?; -// -// //convert to secretbox key -// let sym_key = chacha20poly1305_ietf::Key::from_slice(&decrypted_cek[..]).map_err(|err| { -// CryptoError::UnknownCryptoError(format!("Failed to decrypt sym_key {}", err)) -// })?; -// -// //return key -// Ok(sym_key) -// } - -// /* Authcrypt helper function section */ -// pub fn auth_encrypt_recipient( -// &self, -// my_key: &Key, -// recp_vk: &str, -// sym_key: &chacha20poly1305_ietf -// ) -> Result { -// //encrypt sym_key for recipient -// let (e_cek, cek_nonce) = self.crypto_box(my_key, recp_vk, &sym_key[..])?; -// -// //serialize enc_header -// let sender_vk_bytes = base58::decode(&my_key.verkey).map_err(|err| { -// CryptoError::CommonError(err) -// })?; -// -// //encrypt enc_from -// let enc_from = self.crypto_box_seal(recp_vk, sender_vk_bytes.as_slice())?; -// -// //create struct -// let auth_recipient = AuthRecipient { -// enc_from: base64::encode(enc_from.as_slice()), -// e_cek: base64::encode(e_cek.as_slice()), -// cek_nonce: base64::encode(cek_nonce.as_slice()), -// to: recp_vk.to_string(), -// }; -// -// //return AuthRecipient struct -// Ok(auth_recipient) -// } -// -// pub fn auth_decrypt_recipient( -// &self, -// my_key: &Key, -// auth_recipient: Recipient -// ) -> Result<(chacha20poly1305_ietf::Key, String), CryptoError> { -// //decode enc_from -// let enc_from_bytes = base64::decode(&auth_recipient.enc_from) -// .map_err(|err| CryptoError::CommonError(err))?; -// -// //decrypt enc_from -// let sender_vk_as_vec = self.crypto_box_seal_open(my_key, enc_from_bytes.as_ref())?; -// -// //encode sender_vk to base58 to use to decrypt cek -// let sender_vk = base58::encode(sender_vk_as_vec.as_ref()); -// -// //decode e_cek -// let e_cek_as_vec = base64::decode(&auth_recipient.e_cek) -// .map_err(|err| CryptoError::CommonError(err))?; -// let e_cek: &[u8] = e_cek_as_vec.as_ref(); -// -// //type convert cek_nonce -// let cek_nonce_as_vec = base64::decode(&auth_recipient.cek_nonce).map_err(|err| { -// CryptoError::CommonError(err) -// })?; -// let cek_nonce: &[u8] = cek_nonce_as_vec.as_ref(); -// -// //decrypt cek -// let decrypted_cek = self.crypto_box_open(my_key, &sender_vk, e_cek, cek_nonce)?; -// -// //convert to secretbox key -// let sym_key = xsalsa20::Key::from_slice(&decrypted_cek[..]).map_err( |err| { -// CommonError::InvalidStructure(format!("Failed to unpack sym_key {}", err)) -// })?; -// -// //TODO Verify key is in DID Doc -// -// //return key to decrypt ciphertext and the key used to decrypt with -// Ok((sym_key, sender_vk)) -// } - - pub fn encrypt_plaintext(&self, plaintext: &str) -> (chacha20poly1305_ietf::Key, chacha20poly1305_ietf::Nonce, Vec) { - let sym_key = gen_key(); - let (message, iv) = gen_nonce_and_encrypt(plaintext.as_bytes(), &sym_key); - - (sym_key, iv, message) + pub fn encrypt_plaintext(&self, + plaintext: Vec, + aad: &str, + cek: &chacha20poly1305_ietf::Key) + -> (String, String, String) { + + //encrypt message with aad + let (ciphertext, iv, tag) = gen_nonce_and_encrypt_detached( + plaintext.as_slice(), aad.as_bytes(), &cek); + + //base64 url encode data + let iv_encoded = base64::encode(&iv[..]); + let ciphertext_encoded = base64::encode(ciphertext.as_slice()); + let tag_encoded = base64::encode(&tag[..]); + + (ciphertext_encoded, iv_encoded, tag_encoded) } /* ciphertext helper functions*/ pub fn decrypt_ciphertext( &self, ciphertext: &str, + aad: &str, iv: &str, - sym_key: &chacha20poly1305_ietf::Key, + tag: &str, + cek: &chacha20poly1305_ietf::Key, ) -> Result { + //convert ciphertext to bytes + let ciphertext_as_vec = base64::decode(ciphertext).map_err(|err| { + CryptoError::CommonError( + CommonError::InvalidStructure(format!("Failed to decode ciphertext {}", err)) + ) + })?; + let ciphertext_as_bytes = ciphertext_as_vec.as_ref(); + //convert IV from &str to &Nonce let iv_as_vec = base64::decode(iv).map_err(|err| CryptoError::CommonError( @@ -593,17 +497,26 @@ impl CryptoService { ) })?; - //convert ciphertext to bytes - let ciphertext_as_vec = base64::decode(ciphertext).map_err(|err| { + //convert tag from &str to &Tag + let tag_as_vec = base64::decode(tag).map_err(|err| CryptoError::CommonError( - CommonError::InvalidStructure(format!("Failed to decode ciphertext {}", err)) + CommonError::InvalidStructure(format!("Failed to decode tag {}", err))) + )?; + let tag_as_slice = tag_as_vec.as_slice(); + let tag = chacha20poly1305_ietf::Tag::from_slice(tag_as_slice).map_err(|err| { + CryptoError::CommonError( + CommonError::InvalidStructure(format!("Failed to convert tag to Tag type {}", err)) ) })?; - let ciphertext_as_bytes = ciphertext_as_vec.as_ref(); //decrypt message let plaintext_bytes = - chacha20poly1305_ietf::decrypt(ciphertext_as_bytes, sym_key, &nonce).map_err(|err| { + chacha20poly1305_ietf::decrypt_detached(ciphertext_as_bytes, + cek, + &nonce, + &tag, + Some(aad.as_bytes())) + .map_err(|err| { CryptoError::UnknownCryptoError(format!("Failed to decrypt ciphertext {}", err)) })?; @@ -621,6 +534,7 @@ impl CryptoService { mod tests { use super::*; use domain::crypto::did::MyDidInfo; + use utils::crypto::chacha20poly1305_ietf::gen_key; #[test] fn create_my_did_with_works_for_empty_info() { @@ -895,148 +809,121 @@ mod tests { #[test] pub fn test_encrypt_plaintext_and_decrypt_ciphertext_works() { let service: CryptoService = CryptoService::new(); - let message : &str = "Message to encrypt"; + let plaintext = "Hello World".as_bytes().to_vec(); + let aad = "Random authenticated additional data"; + let cek = gen_key(); - let (sym_key, iv, expected_ciphertext) = service - .encrypt_plaintext(message); + let (expected_ciphertext, iv_encoded, tag) = service + .encrypt_plaintext(plaintext.clone(), aad, &cek); - //convert values to base64 encoded strings - let plaintext_str = base64::encode(expected_ciphertext.as_slice()); - let iv_encoded = base64::encode(&iv[..]); let expected_plaintext = service - .decrypt_ciphertext(&plaintext_str, &iv_encoded, &sym_key).unwrap(); - assert_eq!(expected_plaintext, message); + .decrypt_ciphertext(&expected_ciphertext, aad, &iv_encoded, &tag, &cek).unwrap(); + + assert_eq!(expected_plaintext.as_bytes().to_vec(), plaintext); } #[test] pub fn test_encrypt_plaintext_decrypt_ciphertext_empty_string_works() { let service: CryptoService = CryptoService::new(); - let message : &str = ""; + let plaintext = "".as_bytes().to_vec(); + let aad = "Random authenticated additional data"; + let cek = gen_key(); - let (sym_key, iv, expected_ciphertext) = service - .encrypt_plaintext(message); + let (expected_ciphertext, iv_encoded, tag) = service + .encrypt_plaintext(plaintext.clone(), aad, &cek); - //convert values to base64 encoded strings - let plaintext_str = base64::encode(expected_ciphertext.as_slice()); - let iv_encoded = base64::encode(&iv[..]); let expected_plaintext = service - .decrypt_ciphertext(&plaintext_str, &iv_encoded, &sym_key).unwrap(); - assert_eq!(expected_plaintext, message); + .decrypt_ciphertext(&expected_ciphertext, aad, &iv_encoded, &tag, &cek).unwrap(); + + assert_eq!(expected_plaintext.as_bytes().to_vec(), plaintext); } #[test] pub fn test_encrypt_plaintext_decrypt_ciphertext_bad_iv_fails() { let service: CryptoService = CryptoService::new(); - let message : &str = "hello world"; + let plaintext = "Hello World".as_bytes().to_vec(); + let aad = "Random authenticated additional data"; + let cek = gen_key(); - let (sym_key, iv, expected_ciphertext) = service - .encrypt_plaintext(message); + let (expected_ciphertext, _, tag) = service + .encrypt_plaintext(plaintext, aad, &cek); //convert values to base64 encoded strings - let plaintext_str = base64::encode(expected_ciphertext.as_slice()); let bad_iv_input = "invalid_iv"; let expected_error = service - .decrypt_ciphertext(&plaintext_str, bad_iv_input, &sym_key); + .decrypt_ciphertext(&expected_ciphertext, bad_iv_input, &tag, aad, &cek); assert!(expected_error.is_err()); } #[test] pub fn test_encrypt_plaintext_decrypt_ciphertext_bad_ciphertext_fails() { let service: CryptoService = CryptoService::new(); - let message : &str = "hello world"; + let plaintext = "Hello World".as_bytes().to_vec(); + let aad = "Random authenticated additional data"; + let cek = gen_key(); - let (sym_key, iv, expected_ciphertext) = service - .encrypt_plaintext(message); + let (_, iv_encoded, tag) = service + .encrypt_plaintext(plaintext, aad, &cek); - //convert values to base64 encoded strings let bad_ciphertext= base64::encode("bad_ciphertext".as_bytes()); - let iv_encoded = base64::encode(&iv[..]); let expected_error = service - .decrypt_ciphertext(&bad_ciphertext, &iv_encoded, &sym_key); + .decrypt_ciphertext(&bad_ciphertext, &iv_encoded, &tag, aad, &cek); assert!(expected_error.is_err()); } #[test] - pub fn test_encrypt_plaintext_and_decrypt_ciphertext_wrong_sym_key_fails() { + pub fn test_encrypt_plaintext_and_decrypt_ciphertext_wrong_cek_fails() { let service: CryptoService = CryptoService::new(); - let message : &str = "Message to encrypt"; + let plaintext = "Hello World".as_bytes().to_vec(); + let aad = "Random authenticated additional data"; + let cek = chacha20poly1305_ietf::gen_key(); - let (sym_key, iv, expected_ciphertext) = service - .encrypt_plaintext(message); + let (expected_ciphertext, iv_encoded, tag) = service + .encrypt_plaintext(plaintext, aad, &cek); - //convert values to base64 encoded stringsT - let plaintext_str = base64::encode(expected_ciphertext.as_slice()); - let iv_encoded = base64::encode(&iv[..]); - let bad_sym_key = chacha20poly1305_ietf::gen_key(); + let bad_cek= gen_key(); + + let expected_error = service + .decrypt_ciphertext(&expected_ciphertext, &iv_encoded, &tag, aad, &bad_cek); + assert!(expected_error.is_err()); + } + + #[test] + pub fn test_encrypt_plaintext_and_decrypt_ciphertext_bad_tag_fails() { + let service: CryptoService = CryptoService::new(); + let plaintext = "Hello World".as_bytes().to_vec(); + let aad = "Random authenticated additional data"; + let cek = gen_key(); + + let (expected_ciphertext, iv_encoded, _) = service + .encrypt_plaintext(plaintext, aad, &cek); + + let bad_tag = "bad_tag".to_string(); let expected_error = service - .decrypt_ciphertext(&plaintext_str, &iv_encoded, &bad_sym_key); + .decrypt_ciphertext(&expected_ciphertext, &iv_encoded, &bad_tag, aad, &cek); assert!(expected_error.is_err()); } + #[test] + pub fn test_encrypt_plaintext_and_decrypt_ciphertext_bad_aad_fails() { + let service: CryptoService = CryptoService::new(); + let plaintext = "Hello World".as_bytes().to_vec(); + let aad = "Random authenticated additional data"; + let cek = gen_key(); + let (expected_ciphertext, iv_encoded, tag) = service + .encrypt_plaintext(plaintext, aad, &cek); + let bad_aad = "bad aad"; -// #[test] -// pub fn test_auth_encrypt_recipient_works() { -// //setup route_service -// let service: CryptoService = CryptoService::new(); -// -// //setup DIDs and Keys -// let did_info = MyDidInfo { did: None, cid: None, seed: None, crypto_type: None }; -// let (my_did, my_key) = service.create_my_did(&did_info).unwrap(); -// let (their_did, their_key) = service.create_my_did(&did_info.clone()).unwrap(); -// -// let my_key_for_encrypt = my_key.clone(); -// let their_did_for_encrypt = Did::new(their_did.did, their_did.verkey); -// -// let my_key_for_decrypt = their_key.clone(); -// let their_did_for_decrypt = Did::new(my_did.did, my_did.verkey); -// -// //sym_key -// let sym_key = chacha20poly1305_ietf::gen_key(); -// -// //pack then unpack message -// let auth_recipient = service -// .auth_encrypt_recipient(&my_key_for_encrypt, &their_did_for_encrypt.verkey, &sym_key); -// -// //verify no errors are thrown -// assert!(auth_recipient.is_ok()); -// } - -// pub fn test_auth_encrypt_and_auth_decrypt_recipient_works() { -// //setup route_service -// let service: CryptoService = CryptoService::new(); -// -// //setup DIDs and Keys -// let did_info = MyDidInfo { did: None, cid: None, seed: None, crypto_type: None }; -// let (my_did, my_key) = service.create_my_did(&did_info).unwrap(); -// let (their_did, their_key) = service.create_my_did(&did_info.clone()).unwrap(); -// -// let my_key_for_encrypt = my_key.clone(); -// let their_did_for_encrypt = Did::new(their_did.did, their_did.verkey); -// -// let my_key_for_decrypt = their_key.clone(); -// let their_did_for_decrypt = Did::new(my_did.did, my_did.verkey); -// -// //sym_key -// let sym_key = xsalsa20::create_key(); -// -// //pack then unpack message -// let auth_recipient = service -// .auth_encrypt_recipient(&my_key_for_encrypt, &their_did_for_encrypt.verkey, &sym_key); -// -// let (expected_sym_key, sender_vk) = service -// .auth_decrypt_recipient(&recv_key, auth_recipient, cs.clone()) -// .unwrap(); -// -// //verify same plaintext goes in and comes out -// assert_eq!(expected_sym_key, sym_key); -// assert_eq!(expected_send_key.verkey, sender_vk); -// } + let expected_error = service + .decrypt_ciphertext(&expected_ciphertext, &iv_encoded, &tag, bad_aad, &cek); + assert!(expected_error.is_err()); + } } \ No newline at end of file diff --git a/libindy/src/services/ledger/mod.rs b/libindy/src/services/ledger/mod.rs index 31ef1a728e..daaebb4fa9 100644 --- a/libindy/src/services/ledger/mod.rs +++ b/libindy/src/services/ledger/mod.rs @@ -20,7 +20,7 @@ use domain::anoncreds::DELIMITER; use domain::anoncreds::revocation_registry_definition::{RevocationRegistryDefinition, RevocationRegistryDefinitionV1}; use domain::anoncreds::revocation_registry::RevocationRegistry; use domain::anoncreds::revocation_registry_delta::{RevocationRegistryDelta, RevocationRegistryDeltaV1}; -use domain::anoncreds::schema::{Schema, SchemaV1}; +use domain::anoncreds::schema::{Schema, SchemaV1, MAX_ATTRIBUTES_COUNT}; use domain::anoncreds::credential_definition::{CredentialDefinition, CredentialDefinitionV1}; use indy_crypto::cl::RevocationRegistryDelta as CryproRevocationRegistryDelta; @@ -149,6 +149,11 @@ impl LedgerService { pub fn build_schema_request(&self, identifier: &str, schema: SchemaV1) -> Result { info!("build_schema_request >>> identifier: {:?}, schema: {:?}", identifier, schema); + if schema.attr_names.len() > MAX_ATTRIBUTES_COUNT { + return Err(CommonError::InvalidStructure( + format!("The number of Schema attributes {} cannot be greater than {}", schema.attr_names.len(), MAX_ATTRIBUTES_COUNT))); + } + let schema_data = SchemaOperationData::new(schema.name, schema.version, schema.attr_names); let operation = SchemaOperation::new(schema_data); @@ -805,6 +810,24 @@ mod tests { check_request(&request, expected_result); } + #[test] + fn build_schema_request_works_for_attrs_count_more_than_acceptable() { + let ledger_service = LedgerService::new(); + + let attr_names: AttributeNames = (0..MAX_ATTRIBUTES_COUNT + 1).map(|i| i.to_string()).collect(); + + let data = SchemaV1 { + id: Schema::schema_id(IDENTIFIER, "name", "1.0"), + name: "name".to_string(), + version: "1.0".to_string(), + attr_names, + seq_no: None, + }; + + let res = ledger_service.build_schema_request(IDENTIFIER, data); + assert_match!(Err(CommonError::InvalidStructure(_)), res); + } + #[test] fn build_get_schema_request_works_for_invalid_id() { let ledger_service = LedgerService::new(); diff --git a/libindy/src/services/mod.rs b/libindy/src/services/mod.rs index 8359d4642d..ea1ae0535f 100644 --- a/libindy/src/services/mod.rs +++ b/libindy/src/services/mod.rs @@ -5,4 +5,3 @@ pub mod ledger; pub mod payments; pub mod pool; pub mod wallet; -pub mod agent; diff --git a/libindy/src/utils/crypto/chacha20poly1305_ietf/sodium.rs b/libindy/src/utils/crypto/chacha20poly1305_ietf/sodium.rs index f9a49602a8..2236aa5605 100644 --- a/libindy/src/utils/crypto/chacha20poly1305_ietf/sodium.rs +++ b/libindy/src/utils/crypto/chacha20poly1305_ietf/sodium.rs @@ -17,6 +17,7 @@ pub const TAGBYTES: usize = chacha20poly1305_ietf::TAGBYTES; sodium_type!(Key, chacha20poly1305_ietf::Key, KEYBYTES); sodium_type!(Nonce, chacha20poly1305_ietf::Nonce, NONCEBYTES); +sodium_type!(Tag, chacha20poly1305_ietf::Tag, TAGBYTES); impl Nonce { pub fn increment(&mut self) { @@ -52,6 +53,33 @@ pub fn gen_nonce_and_encrypt(data: &[u8], key: &Key) -> (Vec, Nonce) { (encrypted_data, nonce) } +pub fn gen_nonce_and_encrypt_detached(data: &[u8], aad: &[u8], key: &Key) -> (Vec, Nonce, Tag) { + let nonce = gen_nonce(); + + let mut plain = data.to_vec(); + let tag = chacha20poly1305_ietf::seal_detached( + plain.as_mut_slice(), + Some(aad), + &nonce.0, + &key.0 + ); + + (plain.to_vec(), nonce, Tag(tag)) +} + + +pub fn decrypt_detached(data: &[u8], key: &Key, nonce: &Nonce, tag: &Tag, ad: Option<&[u8]>) -> Result, CommonError> { + let mut plain = data.to_vec(); + chacha20poly1305_ietf::open_detached(plain.as_mut_slice(), + ad, + &tag.0, + &nonce.0, + &key.0, + ).map_err(|err| CommonError::InvalidStructure(format!("Unable to decrypt data: {:?}", err)))?; + + Ok(plain.to_vec()) +} + pub fn encrypt(data: &[u8], key: &Key, nonce: &Nonce) -> Vec { chacha20poly1305_ietf::seal( data, @@ -256,7 +284,7 @@ mod tests { } #[test] - fn encrypt_decrypt_works() { + fn gen_nonce_and_encrypt_decrypt_works() { let data = randombytes(100); let key = gen_key(); @@ -266,6 +294,17 @@ mod tests { assert_eq!(data, u); } + #[test] + pub fn gen_nonce_and_encrypt_detached_decrypt_detached_works() { + let data = randombytes(100); + let key = gen_key(); + let aad= randombytes(100); + + let (c, nonce, tag) = gen_nonce_and_encrypt_detached(&data, aad.as_slice(), &key); + let u = decrypt_detached(&c, &key, &nonce, &tag, Some(aad.as_slice())).unwrap(); + assert_eq!(data, u); +} + #[test] fn encrypt_decrypt_works_for_nonce() { let data = randombytes(16); diff --git a/libindy/src/utils/ctypes.rs b/libindy/src/utils/ctypes.rs index 2f4197f0bf..01ddcbfd94 100644 --- a/libindy/src/utils/ctypes.rs +++ b/libindy/src/utils/ctypes.rs @@ -98,6 +98,7 @@ macro_rules! check_useful_c_str_empty_accepted { } macro_rules! check_useful_opt_c_str { + //TODO This no longer returns None options, only Strings are returned ($x:ident, $e:expr) => { let $x = match ctypes::c_str_to_string($x) { Ok(opt_val) => opt_val.map(String::from), diff --git a/libindy/tests/anoncreds.rs b/libindy/tests/anoncreds.rs index 8fdb895736..5c85191770 100644 --- a/libindy/tests/anoncreds.rs +++ b/libindy/tests/anoncreds.rs @@ -34,7 +34,7 @@ use indy::ErrorCode; use utils::inmem_wallet::InmemWallet; use utils::constants::*; -use utils::domain::anoncreds::schema::Schema; +use utils::domain::anoncreds::schema::{Schema, AttributeNames, MAX_ATTRIBUTES_COUNT}; use utils::domain::anoncreds::credential_definition::CredentialDefinition; use utils::domain::anoncreds::revocation_registry_definition::RevocationRegistryDefinition; use utils::domain::anoncreds::credential::CredentialInfo; @@ -3146,6 +3146,17 @@ mod medium_cases { GVT_SCHEMA_ATTRIBUTES); assert_eq!(res.unwrap_err(), ErrorCode::CommonInvalidStructure); } + + #[test] + fn issuer_create_schema_works_for_attrs_count_more_than_acceptable() { + let attr_names: AttributeNames = (0..MAX_ATTRIBUTES_COUNT + 1).map(|i| i.to_string()).collect(); + + let res = anoncreds::issuer_create_schema(ISSUER_DID, + GVT_SCHEMA_NAME, + SCHEMA_VERSION, + &serde_json::to_string(&attr_names).unwrap()); + assert_eq!(res.unwrap_err(), ErrorCode::CommonInvalidStructure); + } } mod issuer_create_and_store_credential_def { diff --git a/libindy/tests/crypto.rs b/libindy/tests/crypto.rs index 54c28ed4e6..355d24651c 100644 --- a/libindy/tests/crypto.rs +++ b/libindy/tests/crypto.rs @@ -473,6 +473,211 @@ mod high_cases { utils::tear_down_with_wallet(wallet_handle); } } + + mod pack_message_authcrypt { + use super::*; + + #[test] + fn indy_pack_message_authcrypt_works() { + let (wallet_handle, verkey) = setup_with_key(); + let rec_key_vec = vec![VERKEY_MY1, VERKEY_MY2, VERKEY_TRUSTEE]; + let receiver_keys = serde_json::to_string(&rec_key_vec).unwrap(); + let message = "Hello World".as_bytes(); + let res = crypto::pack_message(wallet_handle, message, &receiver_keys, &verkey); + assert!(res.is_ok()); + utils::tear_down_with_wallet(wallet_handle); + } + + #[test] + fn indy_pack_message_authcrypt_fails_empty_message() { + let (wallet_handle, verkey) = setup_with_key(); + let rec_key_vec = vec![VERKEY_MY1, VERKEY_MY2, VERKEY_TRUSTEE]; + let receiver_keys = serde_json::to_string(&rec_key_vec).unwrap(); + let message = "".as_bytes(); + let res = crypto::pack_message(wallet_handle, message, &receiver_keys, &verkey); + assert_eq!(ErrorCode::CommonInvalidParam3, res.unwrap_err()); + utils::tear_down_with_wallet(wallet_handle); + } + + #[test] + fn indy_pack_message_authcrypt_fails_no_receivers() { + let (wallet_handle, verkey) = setup_with_key(); + let receiver_keys = "[]"; + let message = "Hello World".as_bytes(); + let res = crypto::pack_message(wallet_handle, message, &receiver_keys, &verkey); + assert_eq!(ErrorCode::CommonInvalidParam4, res.unwrap_err()); + utils::tear_down_with_wallet(wallet_handle); + } + + #[test] + fn indy_pack_message_authcrypt_fails_bad_wallet_handle() { + let (wallet_handle, verkey) = setup_with_key(); + let rec_key_vec = vec![VERKEY_MY1, VERKEY_MY2, VERKEY_TRUSTEE]; + let receiver_keys = serde_json::to_string(&rec_key_vec).unwrap(); + let message = "Hello World".as_bytes(); + let res = crypto::pack_message(wallet_handle + 1, message, &receiver_keys, &verkey); + assert_eq!(ErrorCode::WalletInvalidHandle, res.unwrap_err()); + utils::tear_down_with_wallet(wallet_handle); + } + + #[test] + fn indy_pack_message_authcrypt_fails_invalid_verkey() { + let (wallet_handle, _) = setup_with_key(); + let rec_key_vec = vec![VERKEY_MY1, VERKEY_MY2, VERKEY_TRUSTEE]; + let receiver_keys = serde_json::to_string(&rec_key_vec).unwrap(); + let message = "Hello World".as_bytes(); + let res = crypto::pack_message(wallet_handle, message, &receiver_keys, INVALID_BASE58_VERKEY); + assert_eq!(ErrorCode::WalletItemNotFound, res.unwrap_err()); + utils::tear_down_with_wallet(wallet_handle); + } + + } + + mod pack_message_anoncrypt { + use super::*; + + #[test] + fn indy_pack_message_anon_works() { + let (wallet_handle, _ ) = setup_with_key(); + let rec_key_vec = vec![VERKEY_MY1, VERKEY_MY2, VERKEY_TRUSTEE]; + let receiver_keys = serde_json::to_string(&rec_key_vec).unwrap(); + let message = "Hello World".as_bytes(); + let res = crypto::pack_message(wallet_handle, message, &receiver_keys, ""); + assert!(res.is_ok()); + utils::tear_down_with_wallet(wallet_handle); + } + + #[test] + fn indy_pack_message_anoncrypt_fails_empty_message() { + let (wallet_handle, _ ) = setup_with_key(); + let rec_key_vec = vec![VERKEY_MY1, VERKEY_MY2, VERKEY_TRUSTEE]; + let receiver_keys = serde_json::to_string(&rec_key_vec).unwrap(); + let message = "".as_bytes(); + let res = crypto::pack_message(wallet_handle, message, &receiver_keys, ""); + assert_eq!(ErrorCode::CommonInvalidParam3, res.unwrap_err()); + utils::tear_down_with_wallet(wallet_handle); + } + + #[test] + fn indy_pack_message_anoncrypt_fails_no_receivers() { + let (wallet_handle, _ ) = setup_with_key(); + let receiver_keys = "[]"; + let message = "Hello World".as_bytes(); + let res = crypto::pack_message(wallet_handle, message, &receiver_keys, ""); + assert_eq!(ErrorCode::CommonInvalidParam4, res.unwrap_err()); + utils::tear_down_with_wallet(wallet_handle); + } + + #[test] + fn indy_pack_message_anoncrypt_passes_bad_wallet_handle() { + let rec_key_vec = vec![VERKEY_MY1, VERKEY_MY2, VERKEY_TRUSTEE]; + let receiver_keys = serde_json::to_string(&rec_key_vec).unwrap(); + let message = "Hello World".as_bytes(); + //The wallet_handle and sender aren't used in this case, so any wallet_handle whether inited or not will work + let res = crypto::pack_message(1, message, &receiver_keys, ""); + assert!(res.is_ok()); + } + + } + + mod unpack_message_authcrypt { + use super::*; + + #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] + pub struct UnpackMessage { + pub message: String, + pub sender_verkey: String + } + + #[test] + fn indy_unpack_message_authcrypt_works() { + //Test setup + let (wallet_handle_sender, sender_verkey) = setup_with_key(); + let (wallet_handle_receiver, receiver_verkey) = setup_with_key(); + let rec_key_vec = vec![VERKEY_TRUSTEE, &receiver_verkey]; + let receiver_keys = serde_json::to_string(&rec_key_vec).unwrap(); + let message = "Hello World".as_bytes(); + let pack_message = crypto::pack_message(wallet_handle_sender, message, &receiver_keys, &sender_verkey).unwrap(); + + //execute function + let res = crypto::unpack_message(wallet_handle_receiver, pack_message.as_slice()).unwrap(); + let res_serialized : UnpackMessage = serde_json::from_slice(res.as_slice()).unwrap(); + + //verify unpack ran correctly + assert_eq!(res_serialized.message, "Hello World".to_string()); + assert_eq!(res_serialized.sender_verkey, sender_verkey); + + //teardown + utils::tear_down_with_wallet(wallet_handle_sender); + utils::tear_down_with_wallet(wallet_handle_receiver); + } + + #[test] + fn indy_unpack_message_authcrypt_fails_no_matching_key() { + //Test Setup + let (wallet_handle_sender, sender_verkey) = setup_with_key(); + let (wallet_handle_receiver, _) = setup_with_key(); + let rec_key_vec = vec![VERKEY_TRUSTEE]; + let receiver_keys = serde_json::to_string(&rec_key_vec).unwrap(); + let message = "Hello World".as_bytes(); + let pack_message = crypto::pack_message(wallet_handle_sender, message, &receiver_keys, &sender_verkey).unwrap(); + + //execute function + let res = crypto::unpack_message(wallet_handle_receiver, pack_message.as_slice()); + + assert_eq!(ErrorCode::WalletItemNotFound, res.unwrap_err()); + + utils::tear_down_with_wallet(wallet_handle_sender); + utils::tear_down_with_wallet(wallet_handle_receiver); + } + + } + + mod unpack_message_anoncrypt { + use super::*; + + #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] + pub struct UnpackMessage { + pub message: String + } + + #[test] + fn indy_unpack_message_anoncrypt_works() { + let (wallet_handle_sender, _) = setup_with_key(); + let (wallet_handle_receiver, receiver_verkey) = setup_with_key(); + let rec_key_vec = vec![VERKEY_TRUSTEE, &receiver_verkey]; + let receiver_keys = serde_json::to_string(&rec_key_vec).unwrap(); + let message = "Hello World".as_bytes(); + let pack_message = crypto::pack_message(wallet_handle_sender, message, &receiver_keys, "").unwrap(); + let res = crypto::unpack_message(wallet_handle_receiver, pack_message.as_slice()).unwrap(); + let res_serialized : UnpackMessage = serde_json::from_slice(res.as_slice()).unwrap(); + + assert_eq!(res_serialized.message, "Hello World".to_string()); + + utils::tear_down_with_wallet(wallet_handle_sender); + utils::tear_down_with_wallet(wallet_handle_receiver); + } + + #[test] + fn indy_unpack_message_anoncrypt_fails_no_matching_key() { + //Test Setup + let (wallet_handle_sender, _) = setup_with_key(); + let (wallet_handle_receiver, _) = setup_with_key(); + let rec_key_vec = vec![VERKEY_TRUSTEE]; + let receiver_keys = serde_json::to_string(&rec_key_vec).unwrap(); + let message = "Hello World".as_bytes(); + let pack_message = crypto::pack_message(wallet_handle_sender, message, &receiver_keys, "").unwrap(); + + //execute function + let res = crypto::unpack_message(wallet_handle_receiver, pack_message.as_slice()); + + assert_eq!(ErrorCode::WalletItemNotFound, res.unwrap_err()); + + utils::tear_down_with_wallet(wallet_handle_sender); + utils::tear_down_with_wallet(wallet_handle_receiver); + } + + } } mod load { diff --git a/libindy/tests/utils/crypto.rs b/libindy/tests/utils/crypto.rs index ea4f0c0c81..85b3feeaeb 100644 --- a/libindy/tests/utils/crypto.rs +++ b/libindy/tests/utils/crypto.rs @@ -40,3 +40,11 @@ pub fn anon_crypt(their_vk: &str, msg: &[u8]) -> Result, ErrorCode> { pub fn anon_decrypt(wallet_handle: i32, my_vk: &str, encrypted_msg: &[u8]) -> Result, ErrorCode> { crypto::anon_decrypt(wallet_handle, my_vk, encrypted_msg).wait() } + +pub fn pack_message(wallet_handle: i32, message: &[u8], receiver_keys: &str, sender: &str) -> Result, ErrorCode> { + crypto::pack_message(wallet_handle, message, receiver_keys, sender).wait() +} + +pub fn unpack_message(wallet_handle: i32, jwe: &[u8]) -> Result, ErrorCode> { + crypto::unpack_message(wallet_handle, jwe).wait() +} \ No newline at end of file diff --git a/vcx/libvcx/src/api/schema.rs b/vcx/libvcx/src/api/schema.rs index aa23bcbd55..af67f83c78 100644 --- a/vcx/libvcx/src/api/schema.rs +++ b/vcx/libvcx/src/api/schema.rs @@ -22,7 +22,7 @@ use utils::threadpool::spawn; /// /// version: version of schema /// -/// schema_data: list of attributes that will make up the schema +/// schema_data: list of attributes that will make up the schema (the number of attributes should be less or equal than 125) /// /// # Example schema_data -> "["attr1", "attr2", "attr3"]" /// diff --git a/vcx/wrappers/node/src/api/schema.ts b/vcx/wrappers/node/src/api/schema.ts index 944e895923..93360c4e4c 100644 --- a/vcx/wrappers/node/src/api/schema.ts +++ b/vcx/wrappers/node/src/api/schema.ts @@ -18,7 +18,7 @@ export interface ISchemaCreateData { * @description * name: name of schema * version: - * attrNames: a list of named attribtes inteded to be added to the schema + * attrNames: a list of named attribtes inteded to be added to the schema (the number of attributes should be less or equal than 125) */ export interface ISchemaAttrs { name: string, diff --git a/vcx/wrappers/python3/vcx/api/schema.py b/vcx/wrappers/python3/vcx/api/schema.py index 56e0c1eabc..a27edb8720 100644 --- a/vcx/wrappers/python3/vcx/api/schema.py +++ b/vcx/wrappers/python3/vcx/api/schema.py @@ -13,7 +13,7 @@ class Schema(VcxBase): Attributes: source_id: user generated unique identifier schema_id: the ledger ID of the schema - attrs: attribute/value pairs + attrs: attribute/value pairs (the number of attributes should be less or equal than 125) version: version of the schema """ diff --git a/wrappers/ios/libindy-pod/Indy/Wrapper/IndyAnoncreds.h b/wrappers/ios/libindy-pod/Indy/Wrapper/IndyAnoncreds.h index 56dc1aa4d5..c1426cb1f1 100644 --- a/wrappers/ios/libindy-pod/Indy/Wrapper/IndyAnoncreds.h +++ b/wrappers/ios/libindy-pod/Indy/Wrapper/IndyAnoncreds.h @@ -23,7 +23,7 @@ @param issuerDID DID of schema issuer @param name a name the schema @param version a version of the schema - @param attrs a list of schema attributes descriptions + @param attrs a list of schema attributes descriptions (the number of attributes should be less or equal than 125) @param completion Callback that takes command result as parameter. Returns: schemaId: identifier of created schema diff --git a/wrappers/ios/libindy-pod/Indy/Wrapper/IndyLedger.h b/wrappers/ios/libindy-pod/Indy/Wrapper/IndyLedger.h index aa56d2459d..0d7d395c01 100644 --- a/wrappers/ios/libindy-pod/Indy/Wrapper/IndyLedger.h +++ b/wrappers/ios/libindy-pod/Indy/Wrapper/IndyLedger.h @@ -185,7 +185,7 @@ @param data Credential schema. { id: identifier of schema - attrNames: array of attribute name strings + attrNames: array of attribute name strings (the number of attributes should be less or equal than 125) name: Schema's name string version: Schema's version string, ver: Version of the Schema json diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/anoncreds/Anoncreds.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/anoncreds/Anoncreds.java index 1e2e51c71e..3aff9384f5 100644 --- a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/anoncreds/Anoncreds.java +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/anoncreds/Anoncreds.java @@ -164,7 +164,7 @@ public void callback(int xcommand_handle, int err, Boolean valid) { * @param issuerDid The DID of the issuer. * @param name Human-readable name of schema. * @param version Version of schema. - * @param attrs: List of schema attributes descriptions + * @param attrs: List of schema attributes descriptions (the number of attributes should be less or equal than 125) * @return A future resolving to IssuerCreateSchemaResult object containing: * schemaId: identifier of created schema * schemaJson: schema as json diff --git a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/ledger/Ledger.java b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/ledger/Ledger.java index 86bdd613e3..dbc2e84d2e 100644 --- a/wrappers/java/src/main/java/org/hyperledger/indy/sdk/ledger/Ledger.java +++ b/wrappers/java/src/main/java/org/hyperledger/indy/sdk/ledger/Ledger.java @@ -511,7 +511,7 @@ public static CompletableFuture buildGetNymRequest( * @param data Credential schema. * { * id: identifier of schema - * attrNames: array of attribute name strings + * attrNames: array of attribute name strings (the number of attributes should be less or equal than 125) * name: Schema's name string * version: Schema's version string, * ver: Version of the Schema json diff --git a/wrappers/nodejs/README.md b/wrappers/nodejs/README.md index 2196809f54..b2673bde55 100644 --- a/wrappers/nodejs/README.md +++ b/wrappers/nodejs/README.md @@ -110,7 +110,7 @@ After that can call issuerCreateAndStoreCredentialDef to build corresponding Cre * `issuerDid`: String - DID of schema issuer * `name`: String - a name the schema * `version`: String - a version of the schema -* `attrNames`: Json +* `attrNames`: Json - a list of schema attributes descriptions (the number of attributes should be less or equal than 125) * __->__ [ `id`: String, `schema`: Json ] - schema\_id: identifier of created schema schema\_json: schema as json @@ -1328,7 +1328,7 @@ Builds a SCHEMA request. Request to add Credential's schema. { id: identifier of schema attrNames: array of attribute name strings - name: Schema's name string + name: Schema's name string (the number of attributes should be less or equal than 125) version: Schema's version string, ver: Version of the Schema json } diff --git a/wrappers/python/indy/__init__.py b/wrappers/python/indy/__init__.py index d68cac3eca..657cb31903 100644 --- a/wrappers/python/indy/__init__.py +++ b/wrappers/python/indy/__init__.py @@ -1 +1,26 @@ from indy.error import IndyError +from indy import anoncreds +from indy import blob_storage +from indy import crypto +from indy import did +from indy import ledger +from indy import libindy +from indy import non_secrets +from indy import pairwise +from indy import payment +from indy import pool +from indy import wallet + +__all__ = [ + 'anoncreds', + 'blob_storage', + 'crypto', + 'did', + 'ledger', + 'libindy', + 'non_secrets', + 'pairwise', + 'payment', + 'pool', + 'wallet' +] diff --git a/wrappers/python/indy/anoncreds.py b/wrappers/python/indy/anoncreds.py index aa8cd7d6b4..d954a46c0f 100644 --- a/wrappers/python/indy/anoncreds.py +++ b/wrappers/python/indy/anoncreds.py @@ -24,7 +24,7 @@ async def issuer_create_schema(issuer_did: str, :param issuer_did: DID of schema issuer :param name: a name the schema :param version: a version of the schema - :param attrs: a list of schema attributes descriptions + :param attrs: a list of schema attributes descriptions (the number of attributes should be less or equal than 125) :return: schema_id: identifier of created schema schema_json: schema as json diff --git a/wrappers/python/indy/ledger.py b/wrappers/python/indy/ledger.py index 78e4e4a65a..6e09a02bf4 100644 --- a/wrappers/python/indy/ledger.py +++ b/wrappers/python/indy/ledger.py @@ -433,7 +433,7 @@ async def build_schema_request(submitter_did: str, :param data: Credential schema. { id: identifier of schema - attrNames: array of attribute name strings + attrNames: array of attribute name strings (the number of attributes should be less or equal than 125) name: Schema's name string version: Schema's version string, ver: Version of the Schema json diff --git a/wrappers/rust/indy-sys/src/crypto.rs b/wrappers/rust/indy-sys/src/crypto.rs index 4510b28e80..78d185eb20 100644 --- a/wrappers/rust/indy-sys/src/crypto.rs +++ b/wrappers/rust/indy-sys/src/crypto.rs @@ -71,5 +71,21 @@ extern { encrypted_msg: BString, encrypted_len: u32, cb: Option) -> Error; + + #[no_mangle] + pub fn indy_pack_message(command_handle: Handle, + wallet_handle: Handle, + message: BString, + message_len: u32, + receiver_keys: CString, + sender: CString, + cb: Option) -> Error; + + #[no_mangle] + pub fn indy_unpack_message(command_handle: Handle, + wallet_handle: Handle, + jwe_msg: BString, + jwe_len: u32, + cb: Option) -> Error; } diff --git a/wrappers/rust/src/anoncreds.rs b/wrappers/rust/src/anoncreds.rs index c29270f8ad..51d4acad4c 100644 --- a/wrappers/rust/src/anoncreds.rs +++ b/wrappers/rust/src/anoncreds.rs @@ -31,7 +31,7 @@ use ffi::{ResponseStringStringCB, /// * `issuer_did`: DID of schema issuer /// * `name`: a name the schema /// * `version`: a version of the schema -/// * `attrs`: a list of schema attributes descriptions +/// * `attrs`: a list of schema attributes descriptions (the number of attributes should be less or equal than 125) /// /// # Returns /// * `schema_id`: identifier of created schema diff --git a/wrappers/rust/src/crypto.rs b/wrappers/rust/src/crypto.rs index ced6cfe42e..42f594ae75 100644 --- a/wrappers/rust/src/crypto.rs +++ b/wrappers/rust/src/crypto.rs @@ -274,3 +274,65 @@ fn _anon_decrypt(command_handle: IndyHandle, wallet_handle: IndyHandle, recipien }) } +/// Unpacks a message packed using indy_pack_message which follows the wire message format HIPE +/// +/// +/// +/// # Arguments +/// * `wallet_handle`: wallet handle (created by Wallet::open). +/// * `message`: a pointer to the first byte of the message to be encrypted +/// * `receiver_keys`: a JSON array as a string containing a list of the receivers verkey's +/// * `sender` : a string of the sender's verkey +/// # Returns +/// a json structure in the form of a JWE that contains the encrypted message and associated metadata +pub fn pack_message(wallet_handle: IndyHandle, message: &[u8], receiver_keys: &str, sender: &str) -> Box, Error=ErrorCode>> { + let (receiver, command_handle, cb) = ClosureHandler::cb_ec_slice(); + + let err= _pack_message(command_handle, wallet_handle, message, receiver_keys, sender, cb); + + ResultHandler::slice(command_handle, err, receiver) +} + +fn _pack_message(command_handle: IndyHandle, wallet_handle: IndyHandle, message: &[u8], receiver_keys: &str, sender: &str, cb: Option) -> ErrorCode { + let receiver_keys = c_str!(receiver_keys); + let sender = c_str!(sender); + + ErrorCode::from(unsafe { + crypto::indy_pack_message(command_handle, + wallet_handle, + message.as_ptr() as *const u8, + message.len() as u32, + receiver_keys.as_ptr(), + sender.as_ptr(), + cb) + }) + +} + +/// Unpacks a message packed using indy_pack_message which follows the wire message format HIPE +/// +/// +/// +/// # Arguments +/// * `wallet_handle`: wallet handle (created by Wallet::open). +/// * `jwe`: a pointer to the first byte of the JWE string +/// # Returns +/// a json structure that contains a decrypted message and a sender_verkey if packed with authcrypt +pub fn unpack_message(wallet_handle: IndyHandle, jwe: &[u8]) -> Box, Error=ErrorCode>> { + let (receiver, command_handle, cb) = ClosureHandler::cb_ec_slice(); + + let err= _unpack_message(command_handle, wallet_handle, jwe, cb); + + ResultHandler::slice(command_handle, err, receiver) +} + +fn _unpack_message(command_handle: IndyHandle, wallet_handle: IndyHandle, jwe: &[u8], cb: Option) -> ErrorCode { + ErrorCode::from(unsafe { + crypto::indy_unpack_message(command_handle, + wallet_handle, + jwe.as_ptr() as *const u8, + jwe.len() as u32, + cb) + }) +} + diff --git a/wrappers/rust/src/ledger.rs b/wrappers/rust/src/ledger.rs index fba2fe45d0..09322b29d8 100644 --- a/wrappers/rust/src/ledger.rs +++ b/wrappers/rust/src/ledger.rs @@ -348,7 +348,7 @@ fn _build_get_attrib_request(command_handle: IndyHandle, submitter_did: Option<& /// * `data` - Credential schema. /// { /// id: identifier of schema -/// attrNames: array of attribute name strings +/// attrNames: array of attribute name strings (the number of attributes should be less or equal than 125) /// name: Schema's name string /// version: Schema's version string, /// ver: Version of the Schema json