From dd8dd261d0dacd4344ebf4540943a95193f0ffe7 Mon Sep 17 00:00:00 2001 From: Andrii Iakovenko Date: Mon, 17 Aug 2020 10:10:11 +0300 Subject: [PATCH 1/3] Add test for encryptShared snippets --- .../android/common/snippet/SnippetsTest.kt | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 ethree-common/src/androidTest/java/com/virgilsecurity/android/common/snippet/SnippetsTest.kt diff --git a/ethree-common/src/androidTest/java/com/virgilsecurity/android/common/snippet/SnippetsTest.kt b/ethree-common/src/androidTest/java/com/virgilsecurity/android/common/snippet/SnippetsTest.kt new file mode 100644 index 0000000..281d3b6 --- /dev/null +++ b/ethree-common/src/androidTest/java/com/virgilsecurity/android/common/snippet/SnippetsTest.kt @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2015-2020, Virgil Security, Inc. + * + * Lead Maintainer: Virgil Security Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * (2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * (3) Neither the name of virgil nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.virgilsecurity.android.common.snippet + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.virgilsecurity.android.common.callback.OnGetTokenCallback +import com.virgilsecurity.android.common.utils.TestConfig +import com.virgilsecurity.android.common.utils.TestUtils +import com.virgilsecurity.android.ethree.interaction.EThree +import com.virgilsecurity.common.model.Data +import com.virgilsecurity.sdk.crypto.VirgilCrypto +import org.junit.Assert.assertArrayEquals +import org.junit.Assert.assertNotNull +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.util.* + +/** + * This test covers snippets that used in documentation. + */ +@RunWith(AndroidJUnit4::class) +class SnippetsTest { + + private lateinit var aliceIdentity: String + private lateinit var bobIdentity: String + private lateinit var crypto: VirgilCrypto + private lateinit var aliceEthree: EThree + private lateinit var bobEthree: EThree + + @Before + fun setup() { + this.crypto = VirgilCrypto() + this.aliceIdentity = UUID.randomUUID().toString() + this.aliceEthree = EThree(aliceIdentity, + object : OnGetTokenCallback { + override fun onGetToken(): String { + return TestUtils.generateTokenString(aliceIdentity) + } + }, + TestConfig.context) + assertNotNull(this.aliceEthree) + this.aliceEthree.register().execute() + + this.bobIdentity = UUID.randomUUID().toString() + this.bobEthree = EThree(bobIdentity, + object : OnGetTokenCallback { + override fun onGetToken(): String { + return TestUtils.generateTokenString(bobIdentity) + } + }, + TestConfig.context) + assertNotNull(this.bobEthree) + this.bobEthree.register().execute() + } + + @Test + fun encryptShared_complex() { + val triple = encryptShared() + val p2pEncryptedStreamKeyData = triple.first + val groupEncryptedStreamKeyData = triple.second + val encryptedData = triple.third + + val decryptedData = decryptShared(p2pEncryptedStreamKeyData, groupEncryptedStreamKeyData, encryptedData) + + assertArrayEquals("Hello".toByteArray(), decryptedData) + } + + private fun encryptShared(): Triple { + // encryptShared >> + + // 1. Prepare streams. + val plaintext = "Hello" + val data = plaintext.toByteArray() + val inputStream = ByteArrayInputStream(data) + val inputStreamSize = data.size + val encryptedOutputStream = ByteArrayOutputStream() + + // 2. Encrypt stream. + val streamKeyData = aliceEthree.encryptShared(inputStream, inputStreamSize, encryptedOutputStream) + + // 3. Upload data from `encryptedOutputStream` to a remote storage. + + /** + * Application specific code. + */ + + // 4.1 Encrypt `streamKeyData` to a specific user (peer-to-peer). + val bobCard = aliceEthree.findUser(bobIdentity).get() + val p2pEncryptedStreamKeyData = aliceEthree.authEncrypt(Data(streamKeyData), bobCard) + + // 4.2 Encrypt `streamKeyData` to a group. + val groupId = "group-chat-1" + val bobUsersResult = aliceEthree.findUsers(arrayListOf(bobIdentity)).get() + val aliceGroup = aliceEthree.createGroup(groupId, bobUsersResult).get() + val groupEncryptedStreamKeyData = aliceGroup.encrypt(streamKeyData) + + // 5. Send encrypted `streamKeyData` (p2pEncryptedStreamKeyData, or groupEncryptedStreamKeyData) to destination device. + + /** + * Application specific code. + */ + + // << encryptShared + + return Triple(p2pEncryptedStreamKeyData.value, groupEncryptedStreamKeyData, encryptedOutputStream.toByteArray()) + } + + private fun decryptShared(p2pEncryptedStreamKeyData: ByteArray, groupEncryptedStreamKeyData: ByteArray, encryptedData: ByteArray): ByteArray? { + // decryptShared >> + + // 1. Receive `encryptedStreamKeyData` and download data from the remote storage. + /** + * Application specific code. + */ + + // 2. Prepare streams. + val encryptedInputStream = ByteArrayInputStream(encryptedData) + val decryptedOutputStream = ByteArrayOutputStream() + + // 3. Find initiator's Card. + val aliceCard = bobEthree.findUser(aliceIdentity).get() + + // 4.1 Decrypt `encryptedStreamKeyData` received peer-to-peer. + val p2pDecryptedStreamKeyData = bobEthree.authDecrypt(Data(p2pEncryptedStreamKeyData), aliceCard).value + + // 4.2 Decrypt `encryptedStreamKeyData` received to the group. + val groupId = "group-chat-1" + val bobGroup = bobEthree.loadGroup(groupId, aliceCard).get() // load correspond group + val groupDecryptedStreamKeyData = bobGroup.decrypt(groupEncryptedStreamKeyData, aliceCard) // decrypt key + + // 5. Decrypt stream. + val decryptedStreamKeyData = p2pDecryptedStreamKeyData ?: groupDecryptedStreamKeyData + + bobEthree.decryptShared(encryptedInputStream, decryptedOutputStream, decryptedStreamKeyData, aliceCard) + + // << decryptShared + + return decryptedOutputStream.toByteArray() + } +} \ No newline at end of file From 1cbb2e8c935a533d03bb932dd24e15514d5c3ded Mon Sep 17 00:00:00 2001 From: Andrii Iakovenko Date: Thu, 19 Nov 2020 20:11:48 +0200 Subject: [PATCH 2/3] Resolve flow issues with multiple cards for the same identity --- build.gradle | 2 +- .../ethree_benchmark/EThreeBenchmark.kt | 9 ++++ .../common/exception/GroupException.kt | 1 + .../storage/cloud/CloudTicketStorage.kt | 27 +++++++++--- .../common/worker/AuthorizationWorker.kt | 9 ++-- .../interaction/sync/EThreeGroupsTest.kt | 42 ++++++++++++++++++- .../interaction/sync/EThreeSyncPositive.kt | 26 +++++++++++- .../java/interaction/EThreeTestPositive.java | 36 ++++++++++++++++ 8 files changed, 140 insertions(+), 12 deletions(-) diff --git a/build.gradle b/build.gradle index 5e50f70..ee78a1d 100644 --- a/build.gradle +++ b/build.gradle @@ -141,7 +141,7 @@ def getGradleOrSystemProperty(String name, Project project) { final String BASE_VIRGIL_PACKAGE = 'com.virgilsecurity' // Packages versions -final String SDK_VERSION = '2.0.7' +final String SDK_VERSION = '2.0.8' subprojects { group BASE_VIRGIL_PACKAGE diff --git a/ethree-benchmark/src/androidTest/java/com/virgilsecurity/android/ethree_benchmark/EThreeBenchmark.kt b/ethree-benchmark/src/androidTest/java/com/virgilsecurity/android/ethree_benchmark/EThreeBenchmark.kt index dbd1533..96b2ca6 100644 --- a/ethree-benchmark/src/androidTest/java/com/virgilsecurity/android/ethree_benchmark/EThreeBenchmark.kt +++ b/ethree-benchmark/src/androidTest/java/com/virgilsecurity/android/ethree_benchmark/EThreeBenchmark.kt @@ -149,6 +149,15 @@ class EThreeBenchmark( } } + @Test + fun dummy_test() { + val state = benchmarkRule.getState() + + while (state.keepRunning()) { + UUID.randomUUID() + } + } + companion object { private const val TEXT = "Hello, my name is text. I am here to be encrypted (:" diff --git a/ethree-common/src/main/java/com/virgilsecurity/android/common/exception/GroupException.kt b/ethree-common/src/main/java/com/virgilsecurity/android/common/exception/GroupException.kt index 03e7282..5350b28 100644 --- a/ethree-common/src/main/java/com/virgilsecurity/android/common/exception/GroupException.kt +++ b/ethree-common/src/main/java/com/virgilsecurity/android/common/exception/GroupException.kt @@ -55,5 +55,6 @@ class GroupException @JvmOverloads constructor( GROUP_IS_OUTDATED(ErrorCode.GROUP + 10, "Group is not up to date. Call update or loadGroup."), INCONSISTENT_STATE(ErrorCode.GROUP + 11, "Inconsistent state."), INITIATOR_REMOVAL_FAILED(ErrorCode.GROUP + 12, "Group initiator is not able to remove himself from a group."), + GROUP_ALREADY_EXISTS(ErrorCode.GROUP + 13, "Group with the same ID is already exists."), } } diff --git a/ethree-common/src/main/java/com/virgilsecurity/android/common/storage/cloud/CloudTicketStorage.kt b/ethree-common/src/main/java/com/virgilsecurity/android/common/storage/cloud/CloudTicketStorage.kt index f86645f..b0c986a 100644 --- a/ethree-common/src/main/java/com/virgilsecurity/android/common/storage/cloud/CloudTicketStorage.kt +++ b/ethree-common/src/main/java/com/virgilsecurity/android/common/storage/cloud/CloudTicketStorage.kt @@ -33,6 +33,7 @@ package com.virgilsecurity.android.common.storage.cloud +import com.virgilsecurity.android.common.exception.GroupException import com.virgilsecurity.android.common.model.Ticket import com.virgilsecurity.android.common.storage.local.LocalKeyStorage import com.virgilsecurity.android.common.util.Const @@ -41,6 +42,7 @@ import com.virgilsecurity.common.util.toHexString import com.virgilsecurity.crypto.foundation.GroupSessionMessage import com.virgilsecurity.keyknox.KeyknoxManager import com.virgilsecurity.keyknox.client.* +import com.virgilsecurity.keyknox.exception.KeyknoxServiceException import com.virgilsecurity.sdk.cards.Card import com.virgilsecurity.sdk.crypto.VirgilPublicKey import com.virgilsecurity.sdk.jwt.contract.AccessTokenProvider @@ -80,11 +82,26 @@ internal class CloudTicketStorage internal constructor( sessionId, "$epoch") - keyknoxManager.pushValue(params, - ticketData, - null, - publicKeys + selfKeyPair.publicKey, - selfKeyPair.privateKey) + try { + keyknoxManager.pushValue(params, + ticketData, + null, + publicKeys + selfKeyPair.publicKey, + selfKeyPair.privateKey) + } + catch (e: KeyknoxServiceException) { + // Maybe the group is already exists + var pullParams = KeyknoxPullParams(this.identity, GROUP_SESSION_ROOT, sessionId, "$epoch") + val pulledValue = keyknoxManager.pullValue(pullParams, + publicKeys + selfKeyPair.publicKey, + selfKeyPair.privateKey) + + if (pulledValue != null) { + throw GroupException(GroupException.Description.GROUP_ALREADY_EXISTS) + } else { + throw e + } + } } internal fun getEpochs(sessionId: Data, identity: String): Set { diff --git a/ethree-common/src/main/java/com/virgilsecurity/android/common/worker/AuthorizationWorker.kt b/ethree-common/src/main/java/com/virgilsecurity/android/common/worker/AuthorizationWorker.kt index dc98dd0..6e604ac 100644 --- a/ethree-common/src/main/java/com/virgilsecurity/android/common/worker/AuthorizationWorker.kt +++ b/ethree-common/src/main/java/com/virgilsecurity/android/common/worker/AuthorizationWorker.kt @@ -71,10 +71,13 @@ internal class AuthorizationWorker internal constructor( @Synchronized internal fun unregister() = object : Completable { override fun execute() { val cards = cardManager.searchCards(this@AuthorizationWorker.identity) - val card = cards.firstOrNull() - ?: throw EThreeException(EThreeException.Description.USER_IS_NOT_REGISTERED) + if (cards.isEmpty()) { + throw EThreeException(EThreeException.Description.USER_IS_NOT_REGISTERED) + } + cards.forEach { card -> + cardManager.revokeCard(card.identifier) + } - cardManager.revokeCard(card.identifier) localKeyStorage.delete() privateKeyDeleted() } diff --git a/tests/src/androidTest/java/com/virgilsecurity/android/ethree/interaction/sync/EThreeGroupsTest.kt b/tests/src/androidTest/java/com/virgilsecurity/android/ethree/interaction/sync/EThreeGroupsTest.kt index b0b7299..0b43380 100644 --- a/tests/src/androidTest/java/com/virgilsecurity/android/ethree/interaction/sync/EThreeGroupsTest.kt +++ b/tests/src/androidTest/java/com/virgilsecurity/android/ethree/interaction/sync/EThreeGroupsTest.kt @@ -34,10 +34,12 @@ package com.virgilsecurity.android.ethree.interaction.sync import com.virgilsecurity.android.common.exception.EThreeException +import com.virgilsecurity.android.common.exception.GroupException import com.virgilsecurity.android.common.model.EThreeParams import com.virgilsecurity.android.common.model.FindUsersResult import com.virgilsecurity.android.ethree.interaction.EThree import com.virgilsecurity.android.ethree.utils.TestConfig +import com.virgilsecurity.keyknox.exception.KeyknoxServiceException import com.virgilsecurity.sdk.cards.Card import com.virgilsecurity.sdk.cards.CardManager import com.virgilsecurity.sdk.cards.model.RawSignedModel @@ -53,7 +55,7 @@ import com.virgilsecurity.sdk.jwt.accessProviders.GeneratorJwtProvider import com.virgilsecurity.sdk.storage.DefaultKeyStorage import com.virgilsecurity.sdk.storage.KeyStorage import com.virgilsecurity.sdk.utils.Tuple -import junit.framework.Assert +import org.junit.Assert import org.junit.Before import org.junit.Test import java.util.* @@ -121,6 +123,44 @@ class EThreeGroupsTest { val userTimelineGroup = eThree.createGroup("feed-group-${identity}", userCards).get() } + @Test + fun createGroup_alreadyExists_shouldFail() { + // Register a set of identities + val size = 2 + val otherUsers: MutableSet = mutableSetOf() + for (i in 1..size) { + otherUsers.add(UUID.randomUUID().toString()) + } + Assert.assertEquals(size, otherUsers.size) + + otherUsers.forEach { identity -> + val cardManager = initCardManager(identity) + val rawCard = generateRawCard(identity, cardManager).right + cardManager.publishCard(rawCard) + } + + // Initialize eThree + val params = EThreeParams(identity, {jwtGenerator.generateToken(identity).stringRepresentation()}, TestConfig.context) + val eThree = EThree(params) + eThree.register().execute() + + val userCards = eThree.findUsers( + otherUsers.toList(), + forceReload = true, + checkResult = false + ).get() + val createdGroup = eThree.createGroup("feed-group-${identity}", userCards).get() + Assert.assertNotNull(createdGroup) + + try { + eThree.createGroup("feed-group-${identity}", userCards).get() + Assert.fail("Group with the same Id shouldn't be created"); + } + catch (e: GroupException) { + Assert.assertEquals(GroupException.Description.GROUP_ALREADY_EXISTS, e.description); + } + } + private fun initCardManager(identity: String): CardManager { val cardCrypto = VirgilCardCrypto() return CardManager( diff --git a/tests/src/androidTest/java/com/virgilsecurity/android/ethree/interaction/sync/EThreeSyncPositive.kt b/tests/src/androidTest/java/com/virgilsecurity/android/ethree/interaction/sync/EThreeSyncPositive.kt index abf801f..83a8ef6 100644 --- a/tests/src/androidTest/java/com/virgilsecurity/android/ethree/interaction/sync/EThreeSyncPositive.kt +++ b/tests/src/androidTest/java/com/virgilsecurity/android/ethree/interaction/sync/EThreeSyncPositive.kt @@ -36,7 +36,6 @@ package com.virgilsecurity.android.ethree.interaction.sync import com.virgilsecurity.android.common.callback.OnGetTokenCallback import com.virgilsecurity.android.ethree.interaction.EThree import com.virgilsecurity.android.ethree.utils.TestConfig -import com.virgilsecurity.android.ethree.utils.TestUtils import com.virgilsecurity.keyknox.KeyknoxManager import com.virgilsecurity.keyknox.client.KeyknoxClient import com.virgilsecurity.keyknox.cloud.CloudKeyStorage @@ -79,8 +78,9 @@ class EThreeSyncPositive { private lateinit var identity: String private lateinit var jwtGenerator: JwtGenerator private lateinit var keyStorage: KeyStorage + private lateinit var crypto: VirgilCrypto - @Before fun setup() { + @Before fun setup() { jwtGenerator = JwtGenerator( TestConfig.appId, TestConfig.appKey, @@ -91,6 +91,7 @@ class EThreeSyncPositive { keyStorage = DefaultKeyStorage(TestConfig.DIRECTORY_PATH, TestConfig.KEYSTORE_NAME) identity = UUID.randomUUID().toString() + crypto = VirgilCrypto() } private fun initAndRegisterEThree(identity: String): EThree { @@ -179,6 +180,27 @@ class EThreeSyncPositive { assertEquals(0, cardsUnregistered.size) } + @Test fun unregister_multiple_cards() { + val eThree = initAndRegisterEThree(identity) + assertTrue(keyStorage.exists(identity)) + + // Register one more card for the same identity + val cardManager = initCardManager(identity) + val keyPair1: VirgilKeyPair = crypto.generateKeyPair() + val card2 = cardManager.publishCard(keyPair1.privateKey, keyPair1.publicKey, identity) + + val cards = initCardManager(identity).searchCards(identity) + assertNotNull(cards) + assertEquals(2, cards.size) + + // unregister should remove all cards of the identity + eThree.unregister().execute() + assertFalse(keyStorage.exists(identity)) + + val cardsUnregistered = initCardManager(identity).searchCards(identity) + assertEquals(0, cardsUnregistered.size) + } + // STE-15_2-4 - Sync @Test fun backup_key_after_register() { val password = UUID.randomUUID().toString() diff --git a/tests/src/androidTest/java/com/virgilsecurity/android/ethree/java/interaction/EThreeTestPositive.java b/tests/src/androidTest/java/com/virgilsecurity/android/ethree/java/interaction/EThreeTestPositive.java index 5d9fe26..d98f9cb 100644 --- a/tests/src/androidTest/java/com/virgilsecurity/android/ethree/java/interaction/EThreeTestPositive.java +++ b/tests/src/androidTest/java/com/virgilsecurity/android/ethree/java/interaction/EThreeTestPositive.java @@ -36,11 +36,14 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import com.virgilsecurity.android.common.callback.OnGetTokenCallback; +import com.virgilsecurity.android.common.exception.FindUsersException; +import com.virgilsecurity.android.common.model.FindUsersResult; import com.virgilsecurity.android.ethree.interaction.EThree; import com.virgilsecurity.android.ethree.utils.TestConfig; import com.virgilsecurity.android.ethree.utils.TestUtils; import com.virgilsecurity.common.callback.OnCompleteListener; import com.virgilsecurity.common.callback.OnResultListener; +import com.virgilsecurity.common.model.Result; import com.virgilsecurity.sdk.cards.Card; import com.virgilsecurity.sdk.cards.CardManager; import com.virgilsecurity.sdk.cards.validation.VirgilCardVerifier; @@ -49,6 +52,8 @@ import com.virgilsecurity.sdk.common.TimeSpan; import com.virgilsecurity.sdk.crypto.VirgilAccessTokenSigner; import com.virgilsecurity.sdk.crypto.VirgilCardCrypto; +import com.virgilsecurity.sdk.crypto.VirgilCrypto; +import com.virgilsecurity.sdk.crypto.VirgilKeyPair; import com.virgilsecurity.sdk.crypto.exceptions.CryptoException; import com.virgilsecurity.sdk.jwt.JwtGenerator; import com.virgilsecurity.sdk.jwt.accessProviders.GeneratorJwtProvider; @@ -58,6 +63,7 @@ import org.junit.Test; import org.junit.runner.RunWith; +import java.util.Arrays; import java.util.List; import java.util.UUID; import java.util.concurrent.CountDownLatch; @@ -170,4 +176,34 @@ public void onError(@NotNull Throwable throwable) { }); lock.await(TestUtils.REQUEST_TIMEOUT, TimeUnit.SECONDS); } + + @Test public void search_for_multicards() throws CryptoException, VirgilServiceException { + String identity2 = UUID.randomUUID().toString(); + VirgilCrypto crypto = new VirgilCrypto(); + CardManager cardManager = initCardManager(identity2); + + VirgilKeyPair keyPair1 = crypto.generateKeyPair(); + Card card1 = cardManager.publishCard(keyPair1.getPrivateKey(), keyPair1.getPublicKey(), identity2); + + VirgilKeyPair keyPair2 = crypto.generateKeyPair(); + Card card2 = cardManager.publishCard(keyPair2.getPrivateKey(), keyPair2.getPublicKey(), identity2); + + // Trying to find a single user's card should fail + try { + this.eThree.findUser(identity2).get(); + fail("Duplicate cards exception should be thrown"); + } + catch (FindUsersException e) { + assertEquals(FindUsersException.Description.DUPLICATE_CARDS, e.getDescription()); + } + + try { + // Trying to find all user's cards should fail + this.eThree.findUsers(Arrays.asList(identity2), true).get(); + fail("Duplicate cards exception should be thrown"); + } + catch (FindUsersException e) { + assertEquals(FindUsersException.Description.DUPLICATE_CARDS, e.getDescription()); + } + } } From 3cbc7080c2e6364df7a8ce765113c262371e96a8 Mon Sep 17 00:00:00 2001 From: Andrii Iakovenko Date: Tue, 24 Nov 2020 10:03:00 +0200 Subject: [PATCH 3/3] Fix code align --- .../android/ethree/interaction/sync/EThreeSyncPositive.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/androidTest/java/com/virgilsecurity/android/ethree/interaction/sync/EThreeSyncPositive.kt b/tests/src/androidTest/java/com/virgilsecurity/android/ethree/interaction/sync/EThreeSyncPositive.kt index 83a8ef6..42d4a44 100644 --- a/tests/src/androidTest/java/com/virgilsecurity/android/ethree/interaction/sync/EThreeSyncPositive.kt +++ b/tests/src/androidTest/java/com/virgilsecurity/android/ethree/interaction/sync/EThreeSyncPositive.kt @@ -80,7 +80,7 @@ class EThreeSyncPositive { private lateinit var keyStorage: KeyStorage private lateinit var crypto: VirgilCrypto - @Before fun setup() { + @Before fun setup() { jwtGenerator = JwtGenerator( TestConfig.appId, TestConfig.appKey,