From 3312a1dbf914ce3758d199fcde0da7f64f189ed9 Mon Sep 17 00:00:00 2001 From: Mauro Piazza Date: Wed, 7 Aug 2024 18:01:50 +0200 Subject: [PATCH 1/4] chore(app): parametrize ws host & port with app intents --- README.md | 14 ++++- app/src/main/AndroidManifest.xml | 3 +- .../java/proofcastlabs/tee/MainActivity.kt | 27 +++++++-- scripts/launch.sh | 60 ++++++++++++++++++- 4 files changed, 93 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 8350383..598ed92 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,8 @@ The architecture consists into different layers: ### Steps -1. Create a `local.properties` file into the project's root folder with the path to the android SDK and NDK +1. Link the Rust library project into the rust folder (be sure it compiles when running `cargo build --release`): +2. Create a `local.properties` file into the project's root folder with the path to the android SDK and NDK additional properties as follows: ```env @@ -76,7 +77,7 @@ In order to setup a production-ready instance, you need: 1. Clone https://github.com/proofcastlabs/event-attestator/ 2. Clone https://github.com/proofcastlabs/tee-wrapper-android -3. Follow the setup guide in the `event-attestator` repo and run the jsonrpc-app +3. Follow the setup guide in the `event-attestator` repo and run the jsonrpc-appp artifact with ``` @@ -180,3 +181,12 @@ a compatible keystore and name it `keystore-path.jks`. **note:** here we have used the same password for the keystore access and the only alias `signing-key`. + + +### Websocket connection customization + +You can set the ws host and port to connect by using the launch.sh script: + +```bash + ./scripts/launch.sh -e wsHost 8.8.8.8 -e wsPort 23000 +``` diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f31d23f..a35ae37 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -19,10 +19,9 @@ android:exported="true"> - - \ No newline at end of file + diff --git a/app/src/main/java/proofcastlabs/tee/MainActivity.kt b/app/src/main/java/proofcastlabs/tee/MainActivity.kt index 8a83e2b..d426dec 100644 --- a/app/src/main/java/proofcastlabs/tee/MainActivity.kt +++ b/app/src/main/java/proofcastlabs/tee/MainActivity.kt @@ -3,6 +3,8 @@ package proofcastlabs.tee import android.content.Context +import android.content.Intent +import android.content.IntentFilter import android.os.Bundle import android.util.Log import kotlinx.coroutines.runBlocking @@ -26,9 +28,17 @@ import java.time.Duration class MainActivity : AppCompatActivity() { private external fun callCore(strongbox: Strongbox, db: DatabaseWiring, input: String): String + private val TAG = "[Main]" private val WS_RETRY_DELAY = 3_000L private val WS_PING_INTERVAL = 55_000L + private val WS_DEFAULT_PORT = "3000" + private val WS_DEFAULT_HOST = "localhost" + private val INTENT_KEY_WS_HOST = "wsHost" + private val INTENT_KEY_WS_PORT = "wsPort" + + private var wsHost = "localhost" + private var wsPort = 3000 private val verifyStateHash = BuildConfig.VERIFY_STATE_HASH.toBoolean() private val writeStateHash = BuildConfig.WRITE_STATE_HASH.toBoolean() private val isStrongboxBacked = BuildConfig.STRONGBOX_ENABLED.toBoolean() @@ -36,7 +46,6 @@ class MainActivity : AppCompatActivity() { private var strongbox: Strongbox? = null private var db: DatabaseWiring? = null - val TAG = "[Main]" init { System.loadLibrary("sqliteX") @@ -49,8 +58,8 @@ class MainActivity : AppCompatActivity() { client!!.webSocket( method = HttpMethod.Get, path = "/ws", - host = "127.0.0.1", - port = 3000 + host = wsHost, + port = wsPort ) { Log.i(TAG, "Websocket connected") strongbox = Strongbox(context) @@ -104,6 +113,16 @@ class MainActivity : AppCompatActivity() { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + // Send intent extra by adding --es to the launch.sh + // script + if (intent.extras != null) { + wsHost = intent.extras!!.getString(INTENT_KEY_WS_HOST, WS_DEFAULT_HOST) + wsPort = intent.extras!!.getString(INTENT_KEY_WS_PORT, WS_DEFAULT_PORT).toInt() + } + + Log.d(TAG, "Host: $wsHost") + Log.d(TAG, "Port: $wsPort") + val dns = object : Dns { override fun lookup(hostname: String): List { return Dns.SYSTEM.lookup(hostname).filter { @@ -134,4 +153,4 @@ class MainActivity : AppCompatActivity() { client!!.close() Log.i(TAG, "Websocket connection closed!") } -} \ No newline at end of file +} diff --git a/scripts/launch.sh b/scripts/launch.sh index eec7407..7db75b8 100755 --- a/scripts/launch.sh +++ b/scripts/launch.sh @@ -1,4 +1,58 @@ #!/bin/bash -device="$1" -if [[ -n "$device" ]]; then device="-s $device"; fi -adb $device shell am start proofcastlabs.tee/.MainActivity \ No newline at end of file +function usage { + local b # bold + local n # normal + b=$(tput bold) + n=$(tput sgr0) + + echo "${b}Usage:${n} $0 [DEVICE_ID] [...ADB_ARGS] + + Launch the MainActivity of the Event Attestator on the + selected DEVICE. You may optionally decide to extra adb + parameters, these are going to be appended at the end of + the adb command. + +${b}Arguments:${n} + + DEVICE_ID The device ID show through adb devices command. An empty + value is accepted only when a single device is attached + to the machine. + + ADB_ARGS Parameters accepted by the adb activity manager (am) + command (i.e. intent extras like --es ) + Check the acceptable intent extra keys into the MainActivity + code. + +${b}Available options:${n} + + -h, --help Shows this help + +${b}Examples:${n} + + 1. Launch with websocket host and port settings: + + $0 --es wsHost localhost --es wsPort 11111 + + 2. Launch on a specific device (8BKX1BBEE) + + $0 8BKX1BBEE +" +} + +function main { + if [[ "$1" == "-h" || "$1" == "--help" ]]; then + usage + exit 0 + fi + + if [[ ! "$1" == -* && -n "$1" ]]; then + device="-s $1" + shift 1 + fi + + # You can add params to the launching command (i.e. intents) + # ...such coolness :D + adb $device shell am start -n proofcastlabs.tee/.MainActivity -a android.intent.action.MAIN $@ +} + +main "$@" From 00a98d120b14b7edb3ddae9b062f0221722e0ff2 Mon Sep 17 00:00:00 2001 From: Mauro Piazza Date: Fri, 9 Aug 2024 10:16:51 +0200 Subject: [PATCH 2/4] chore(connect-device): promp user for action --- scripts/connect-device.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/connect-device.sh b/scripts/connect-device.sh index e030b5f..a50e357 100755 --- a/scripts/connect-device.sh +++ b/scripts/connect-device.sh @@ -9,5 +9,5 @@ # lsusb | grep -i google | awk '{print "/dev/bus/usb/"$2"/"$4}' | tr -d ':' | xargs sudo chown "$USER:plugdev" adb kill-server +read -p "Please press 'Allow' on the device display and press enter..." adb devices -adb reverse tcp:3000 tcp:3000 From e7325854d7777ae3655c3036f911d95c96c84a40 Mon Sep 17 00:00:00 2001 From: Mauro Piazza Date: Fri, 9 Aug 2024 17:06:18 +0200 Subject: [PATCH 3/4] chore(app): add logging level --- app/build.gradle | 5 ++-- .../java/proofcastlabs/tee/MainActivity.kt | 24 ++++++++++++------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 31b8b23..1ef1d8f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,7 +18,7 @@ def verifyStateHash = config.getProperty('build.verifyStateHash', 'false') def writeStateHash = config.getProperty('build.writeStateHash', 'false') def buildType = gradle.startParameter.taskNames.any { it.contains("Debug") } ? "debug" : "release" -def ksPath = config.getProperty('ks.path') +def ksPath = config.getProperty('ks.path', './') def ksPassword = config.getProperty('ks.password') def ksAlias = config.getProperty('ks.alias') @@ -130,6 +130,7 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation "io.ktor:ktor-client-core:$ktorVersion" implementation "io.ktor:ktor-client-cio:$ktorVersion" + implementation "io.ktor:ktor-client-logging:$ktorVersion" implementation "io.ktor:ktor-client-websockets:$ktorVersion" implementation "io.ktor:ktor-client-okhttp:$ktorVersion" implementation 'commons-codec:commons-codec:1.17.0' @@ -137,4 +138,4 @@ dependencies { testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' -} \ No newline at end of file +} diff --git a/app/src/main/java/proofcastlabs/tee/MainActivity.kt b/app/src/main/java/proofcastlabs/tee/MainActivity.kt index d426dec..3db7cdc 100644 --- a/app/src/main/java/proofcastlabs/tee/MainActivity.kt +++ b/app/src/main/java/proofcastlabs/tee/MainActivity.kt @@ -3,14 +3,16 @@ package proofcastlabs.tee import android.content.Context -import android.content.Intent -import android.content.IntentFilter import android.os.Bundle import android.util.Log import kotlinx.coroutines.runBlocking import androidx.appcompat.app.AppCompatActivity import io.ktor.client.* import io.ktor.client.engine.okhttp.* +import io.ktor.client.plugins.logging.ANDROID +import io.ktor.client.plugins.logging.LogLevel +import io.ktor.client.plugins.logging.Logger +import io.ktor.client.plugins.logging.Logging import io.ktor.client.plugins.websocket.* import io.ktor.http.* import io.ktor.websocket.* @@ -33,12 +35,15 @@ class MainActivity : AppCompatActivity() { private val WS_PING_INTERVAL = 55_000L private val WS_DEFAULT_PORT = "3000" private val WS_DEFAULT_HOST = "localhost" + private val WS_DEFAULT_TIMEOUT = 10_000L private val INTENT_KEY_WS_HOST = "wsHost" private val INTENT_KEY_WS_PORT = "wsPort" + private val INTENT_KEY_WS_TIMEOUT = "wsTimeout" private var wsHost = "localhost" private var wsPort = 3000 + private var wsTimeout = WS_DEFAULT_TIMEOUT private val verifyStateHash = BuildConfig.VERIFY_STATE_HASH.toBoolean() private val writeStateHash = BuildConfig.WRITE_STATE_HASH.toBoolean() private val isStrongboxBacked = BuildConfig.STRONGBOX_ENABLED.toBoolean() @@ -56,10 +61,11 @@ class MainActivity : AppCompatActivity() { suspend fun receiveWebsocketData(context: Context) { client!!.webSocket( - method = HttpMethod.Get, - path = "/ws", - host = wsHost, - port = wsPort +// method = HttpMethod.Get, +// path = "/ws", +// host = wsHost, +// port = wsPort + "ws://$wsHost:$wsPort/ws" ) { Log.i(TAG, "Websocket connected") strongbox = Strongbox(context) @@ -118,10 +124,12 @@ class MainActivity : AppCompatActivity() { if (intent.extras != null) { wsHost = intent.extras!!.getString(INTENT_KEY_WS_HOST, WS_DEFAULT_HOST) wsPort = intent.extras!!.getString(INTENT_KEY_WS_PORT, WS_DEFAULT_PORT).toInt() + wsTimeout = intent.extras!!.getString(INTENT_KEY_WS_TIMEOUT, WS_DEFAULT_TIMEOUT.toString()).toLong() } Log.d(TAG, "Host: $wsHost") Log.d(TAG, "Port: $wsPort") + Log.d(TAG, "Timeout: $wsTimeout") val dns = object : Dns { override fun lookup(hostname: String): List { @@ -132,7 +140,7 @@ class MainActivity : AppCompatActivity() { } val context = this - val timeout = Duration.ofSeconds(100L) + val timeout = Duration.ofMillis(wsTimeout) client = HttpClient(OkHttp) { engine { config { dns(dns) @@ -140,7 +148,7 @@ class MainActivity : AppCompatActivity() { readTimeout(timeout) connectTimeout(timeout) } } - + install(Logging) { level = LogLevel.ALL; logger = Logger.ANDROID } install(WebSockets) { pingInterval = WS_PING_INTERVAL } } From 10cf8e746fcf1c5017566d37d24be88fe30d434b Mon Sep 17 00:00:00 2001 From: Mauro Piazza Date: Fri, 9 Aug 2024 20:05:16 +0200 Subject: [PATCH 4/4] fix(README): typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 598ed92..ab7a091 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ In order to setup a production-ready instance, you need: 1. Clone https://github.com/proofcastlabs/event-attestator/ 2. Clone https://github.com/proofcastlabs/tee-wrapper-android -3. Follow the setup guide in the `event-attestator` repo and run the jsonrpc-appp +3. Follow the setup guide in the `event-attestator` repo and run the jsonrpc-app artifact with ```