From 95d29aa9ecb09ca08a44a1d6a2dd2ac5ff6236ae Mon Sep 17 00:00:00 2001 From: Joey Harward Date: Wed, 2 Dec 2020 10:02:04 -0500 Subject: [PATCH 1/2] fixed decode and authorize ESR update dagger and greymass lib update version --- buildSrc/src/main/kotlin/Dependencies.kt | 10 +-- .../com/metallicus/protonsdk/AccountModule.kt | 89 ++++++++++++++++--- .../java/com/metallicus/protonsdk/Proton.kt | 8 +- .../protonsdk/api/ESRCallbackService.kt | 6 +- .../metallicus/protonsdk/model/ProtonESR.kt | 2 +- .../protonsdk/repository/ESRRepository.kt | 5 +- 6 files changed, 89 insertions(+), 31 deletions(-) diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt index 6959b12f..c50afad9 100644 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/src/main/kotlin/Dependencies.kt @@ -19,12 +19,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -const val kotlinVersion = "1.4.10" +const val kotlinVersion = "1.4.10" // TODO: 1.4.20 const val orchidVersion = "0.21.1" object ProtonSdk { - const val versionCode = 23 - const val versionName = "0.7.0" + const val versionCode = 24 + const val versionName = "0.7.1" } object BuildPlugins { @@ -66,13 +66,13 @@ object Libraries { const val workManager = "2.4.0" const val okhttp3 = "4.9.0" const val retrofit = "2.9.0" - const val dagger = "2.29.1" + const val dagger = "2.30.1" const val daggerAssistedInject = "0.6.0" const val coroutines = "1.4.0-M1" const val timber = "4.7.1" const val gson = "2.8.6" const val guava = "29.0-jre" - const val esr = "1.0.2" + const val esr = "1.0.4" } const val kotlinStdLib = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/AccountModule.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/AccountModule.kt index 35b143a0..563bc93a 100644 --- a/protonsdk/src/main/java/com/metallicus/protonsdk/AccountModule.kt +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/AccountModule.kt @@ -22,22 +22,27 @@ package com.metallicus.protonsdk import android.content.Context +import android.net.Uri import android.util.Base64 import com.google.gson.* import com.greymass.esr.ESR import com.greymass.esr.SigningRequest +import com.greymass.esr.models.PermissionLevel +import com.greymass.esr.models.TransactionContext import com.metallicus.protonsdk.common.SecureKeys import com.metallicus.protonsdk.common.Prefs import com.metallicus.protonsdk.common.Resource import com.metallicus.protonsdk.di.DaggerInjector import com.metallicus.protonsdk.eosio.commander.digest.Sha256 import com.metallicus.protonsdk.eosio.commander.ec.EosPrivateKey +import com.metallicus.protonsdk.eosio.commander.model.types.TypeChainId import com.metallicus.protonsdk.model.* import com.metallicus.protonsdk.repository.AccountContactRepository import com.metallicus.protonsdk.repository.AccountRepository import com.metallicus.protonsdk.repository.ChainProviderRepository import com.metallicus.protonsdk.repository.ESRRepository import timber.log.Timber +import java.util.* import javax.inject.Inject /** @@ -328,19 +333,25 @@ class AccountModule { return secureKeys.getPrivateKey(publicKey, pin).orEmpty() } - private fun getActiveAccountSignature(pin: String): String { + private fun signActiveAccountName(pin: String): String { val accountName = prefs.getActiveAccountName() - val publicKey = prefs.getActivePublicKey() + return signWithActiveKey(pin, accountName) + } + + private fun signWithActiveKey(pin: String, data: String): String { + return signWithActiveKey(pin, data.toByteArray()) + } + private fun signWithActiveKey(pin: String, data: ByteArray): String { + val publicKey = prefs.getActivePublicKey() val privateKeyStr = secureKeys.getPrivateKey(publicKey, pin) val privateKey = EosPrivateKey(privateKeyStr) - val sha256 = Sha256.from(accountName.toByteArray()) - val signature = privateKey.sign(sha256).toString() - return signature + val sha256 = Sha256.from(data) + return privateKey.sign(sha256).toString() } suspend fun updateAccountName(chainAccount: ChainAccount, pin: String, name: String): Resource { - val signature = getActiveAccountSignature(pin) + val signature = signActiveAccountName(pin) val accountName = chainAccount.account.accountName @@ -371,7 +382,7 @@ class AccountModule { } suspend fun updateAccountAvatar(chainAccount: ChainAccount, pin: String, imageByteArray: ByteArray): Resource { - val signature = getActiveAccountSignature(pin) + val signature = signActiveAccountName(pin) val accountName = chainAccount.account.accountName @@ -426,11 +437,14 @@ class AccountModule { val requestAccountName = signingRequest.info["req_account"].orEmpty() - val requestKey = "" + var requestKey = "" if (signingRequest.isIdentity) { - val linkStr = signingRequest.info["link"] + val linkHexValue = signingRequest.infoPairs.find { + it.key == "link" + }?.hexValue.orEmpty() - // TODO: deserialize link as LinkCreate obj + val linkCreate = signingRequest.decodeLinkCreate(linkHexValue) + requestKey = linkCreate.requestKey } val returnPath = signingRequest.info["return_path"].orEmpty() @@ -474,12 +488,59 @@ class AccountModule { } } - suspend fun authorizeESR(protonESR: ProtonESR): Resource { + fun getAppName(): String { + val applicationInfo = context.applicationInfo + val stringId = applicationInfo.labelRes + return if (stringId == 0) { + applicationInfo.nonLocalizedLabel.toString() + } else { + context.getString(stringId) + } + } + + suspend fun authorizeESR(pin: String, protonESR: ProtonESR): Resource { return try { - val callback = protonESR.signingRequest.callback + val resolvedSigningRequest = + protonESR.signingRequest.resolve( + PermissionLevel(protonESR.signingAccount.account.accountName, "active"), TransactionContext()) - val response = - esrRepository.authorizeESR(callback, "") + protonESR.resolvedSigningRequest = resolvedSigningRequest + + val chainIdStr = protonESR.signingAccount.chainProvider.chainId + val chainIdByteArray = TypeChainId(chainIdStr).bytes + + val transactionByteArray = resolvedSigningRequest.serializedTransaction + + val trailingByteArray = ByteArray(32) + + val unsignedTransactionDigest = chainIdByteArray + transactionByteArray + trailingByteArray + + val signature = signWithActiveKey(pin, unsignedTransactionDigest) + + val callback = resolvedSigningRequest.getCallback(listOf(signature)) + + val sessionKey = EosPrivateKey() + + val sessionChannel = Uri.Builder() + .scheme("https") + .authority("cb.anchor.link") + .appendPath(UUID.randomUUID().toString()) + .build() + + val linkName = getAppName() + + val authParams = callback.payload + authParams["link_key"] = sessionKey.publicKey.toString() + authParams["link_ch"] = sessionChannel.toString() + authParams["link_name"] = linkName + //authParams.remove("SIG") + authParams["sig"] = signature + + val originalESRUrlScheme = protonESR.originESRUrlScheme + ":" + val req = authParams["req"]?.replace("esr:", originalESRUrlScheme) + authParams["req"] = req + + val response = esrRepository.authorizeESR(callback.url, authParams) if (response.isSuccessful) { Resource.success(response.body()) } else { diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/Proton.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/Proton.kt index 09488e06..f942b4f9 100644 --- a/protonsdk/src/main/java/com/metallicus/protonsdk/Proton.kt +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/Proton.kt @@ -519,16 +519,16 @@ class Proton private constructor(context: Context) { } } - fun authorizeESR(protonESR: ProtonESR): LiveData> = liveData { + fun authorizeESR(pin: String, protonESR: ProtonESR): LiveData> = liveData { emit(Resource.loading()) try { - emit(accountModule.authorizeESR(protonESR)) + emit(accountModule.authorizeESR(pin, protonESR)) } catch (e: ProtonException) { - val error: Resource = Resource.error(e) + val error: Resource = Resource.error(e) emit(error) } catch (e: Exception) { - val error: Resource = Resource.error(e.localizedMessage.orEmpty()) + val error: Resource = Resource.error(e.localizedMessage.orEmpty()) emit(error) } } diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/api/ESRCallbackService.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/api/ESRCallbackService.kt index 1cbf46b7..8ef83cf3 100644 --- a/protonsdk/src/main/java/com/metallicus/protonsdk/api/ESRCallbackService.kt +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/api/ESRCallbackService.kt @@ -21,12 +21,10 @@ */ package com.metallicus.protonsdk.api -import com.google.gson.JsonObject import retrofit2.Response import retrofit2.http.* -data class CancelAuthorizeESRBody(val error: String) -data class AuthorizeESRBody(val error: String) +data class CancelAuthorizeESRBody(val rejected: String) interface ESRCallbackService { @POST @@ -37,5 +35,5 @@ interface ESRCallbackService { @POST suspend fun authorizeESR( @Url url: String, - @Body body: AuthorizeESRBody): Response + @Body body: Map): Response } \ No newline at end of file diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/model/ProtonESR.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/model/ProtonESR.kt index 92a932d4..e30f8313 100644 --- a/protonsdk/src/main/java/com/metallicus/protonsdk/model/ProtonESR.kt +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/model/ProtonESR.kt @@ -31,7 +31,7 @@ class ProtonESR( val originESRUrlScheme: String, val requestAccount: Account? = null, val returnPath: String? = "", - val resolvedSigningRequest: ResolvedSigningRequest? = null//, + var resolvedSigningRequest: ResolvedSigningRequest? = null//, //val actions: List ) { fun getRequestAccountDisplayName(): String { diff --git a/protonsdk/src/main/java/com/metallicus/protonsdk/repository/ESRRepository.kt b/protonsdk/src/main/java/com/metallicus/protonsdk/repository/ESRRepository.kt index 2370d084..c637228c 100755 --- a/protonsdk/src/main/java/com/metallicus/protonsdk/repository/ESRRepository.kt +++ b/protonsdk/src/main/java/com/metallicus/protonsdk/repository/ESRRepository.kt @@ -21,7 +21,6 @@ */ package com.metallicus.protonsdk.repository -import com.google.gson.JsonObject import com.metallicus.protonsdk.api.* import retrofit2.Response import javax.inject.Inject @@ -35,7 +34,7 @@ class ESRRepository @Inject constructor( return esrCallbackService.cancelAuthorizeESR(url, CancelAuthorizeESRBody(error)) } - suspend fun authorizeESR(url: String, error: String): Response { - return esrCallbackService.authorizeESR(url, AuthorizeESRBody(error)) + suspend fun authorizeESR(url: String, params: Map): Response { + return esrCallbackService.authorizeESR(url, params) } } From 0390d33f8187f14176d02dbd3cbd10b917ea5d0a Mon Sep 17 00:00:00 2001 From: Joey Harward Date: Thu, 3 Dec 2020 16:30:22 -0500 Subject: [PATCH 2/2] update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8399f851..8855546d 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Then add the following dependency to your module's build.gradle ```gradle dependencies { ... - implementation "com.metallicus:protonsdk:0.7.0" + implementation "com.metallicus:protonsdk:0.7.1" } ```