Skip to content

About

Tor resources for kmp-tor

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

kmp-tor-resource

badge-license badge-latest-release

badge-kotlin badge-build-env badge-kmp-tor-common badge-androidx-startup

badge-platform-android badge-platform-jvm badge-platform-js-node badge-platform-wasm badge-platform-android-native badge-platform-linux badge-platform-macos badge-platform-ios badge-platform-windows

This project is focused on the packaging and distribution of pre-compiled tor resources for Kotlin Multiplatform, primarily to be consumed as a dependency for kmp-tor.

Bisq fork

This is bisq-network/kmp-tor-resource, a fork of 05nelsonm/kmp-tor-resource that publishes tor security releases for the Bisq apps ahead of the upstream release cadence. Changes are kept upstreamable and offered back as pull requests.

  • Releases are published to Maven Central under group io.github.rodvar.kmp-tor (same artifact ids and package names as upstream). The two Gradle plugins are io.github.rodvar.kmp-tor.resource-frameworks and io.github.rodvar.kmp-tor.resource-filterjar, because Maven Central only accepts plugin ids under a namespace the publisher owns. The namespace is the publishing maintainer's, the same trust model as the upstream io.matthewnelson coordinates; once a Bisq-owned namespace (network.bisq) is verified the same tags are re-published there and consumers swap the group.
  • Every file is GPG signed, and each release on GitHub carries a SHA256SUMS list of every published file.
  • Signing key: Bisq kmp-tor-resource signing <kmp-tor-resource@bisq.network>, fingerprint 4ECE E529 847B 49F1 81D6 9A7C 9BC4 7C3D 2AE1 FF8B. The public key is committed as kmp-tor-resource-signing-key.asc and published on keys.openpgp.org:
    gpg --import kmp-tor-resource-signing-key.asc
    # or: gpg --keyserver hkps://keys.openpgp.org --recv-keys 4ECEE529847B49F181D69A7C9BC47C3D2AE1FF8B
    gpg --verify resource-exec-tor-gpl-409.14.0.pom.asc resource-exec-tor-gpl-409.14.0.pom
  • Only Android, iOS and JVM publications are produced. The detached Developer ID signatures under external/codesign can only be regenerated by the upstream maintainer, so this fork gives the Apple compilations (macOS, iOS Simulator) a deterministic ad-hoc signature at packaging (--adhoc-codesign, via rcodesign) and leaves the Windows binaries unsigned. Ad-hoc signed code loads on Apple Silicon and in the iOS Simulator, and runs locally on macOS, but is not notarized: do not distribute the desktop binaries, use the upstream coordinates for that.
  • Every published version rebuilds reproducibly: run the validation steps against the tag and compare with the hashes in build-logic.

Consumer setup (Gradle Kotlin DSL). Releases resolve from mavenCentral():

repositories {
    mavenCentral()
}
dependencies {
    implementation("io.github.rodvar.kmp-tor:resource-exec-tor-gpl:409.14.0")   // Android
    implementation("io.github.rodvar.kmp-tor:resource-noexec-tor-gpl:409.14.0") // iOS
}

Publishing is done by the Publish workflow. A release is: set VERSION_NAME in gradle.properties to the release version, push the tag with the same name, and once the workflow has validated the deployment, release it in the Central Portal. A manual dispatch builds and signs a branch without uploading; with maven_central set it rehearses the Central upload too: use an -rcN version for that and drop the validated deployment in the portal instead of releasing it.

Build Reproducibility

See DETERMINISTIC_BUILDS.md

Compilations

Tor and its dependencies are compiled from source using the following versions

git tag
libevent release-2.1.12-stable
openssl openssl-3.5.5
tor tor-0.4.9.14
xz v5.8.2
zlib v1.3.1

NOTE: All macOS and Windows compilations are code signed so they work out of the box.

More details about how things are compiled can be found HERE

Supported Operating Systems & Architectures for Jvm, Kotlin/Js, & Kotlin/WasmJs

aarch64 armv7a ppc64le riscv64 x86 x86_64
Windows ✔ ✔
macOS ✔ ✔
Linux (android) ✔ ✔ ✔ ✔
Linux (libc) ✔ ✔ ✔ ✔ ✔ ✔
Linux (musl) ✔ ✔ ✔
FreeBSD

Types (exec & noexec)

2 types of resources are available; exec and noexec. This is to support platforms where process execution is not allowed (e.g. iOS).

  • resource-exec-tor and its -gpl variant:

    • Provides an implementation of ResourceLoader.Tor.Exec
    • Support for all platforms except iOS
  • resource-noexec-tor and its -gpl variant:

    • Provides an implementation of ResourceLoader.Tor.NoExec
    • Support for all platforms except Node.js

Even though tremendous work has gone into making the noexec dependencies as safe as possible by unloading tor after each invocation of tor_run_main, there is no safer way to run tor than in its own process (as it was designed). The exec dependency should be utilized whenever possible.

Variants (tor & tor-gpl)

2 variants of tor are compiled; 1 with the flag --enable-gpl, and 1 without it.

Publications with the -gpl suffix are indicative of the presence of the --enable-gpl compile time flag.

Both variants are positionally identical with the same package names, classes, resource names/locations, etc. The only difference between them are the compilations of tor being provided.

Only 1 variant can be had for a project, as a conflict will occur if both are present.

Example

build.gradle.kts

// BAD
dependencies {
    implementation("io.matthewnelson.kmp-tor:resource-exec-tor:$vKmpTorResource")
    implementation("io.matthewnelson.kmp-tor:resource-exec-tor-gpl:$vKmpTorResource")
}

// BAD
dependencies {
    implementation("io.matthewnelson.kmp-tor:resource-exec-tor:$vKmpTorResource")
    implementation("io.matthewnelson.kmp-tor:resource-noexec-tor-gpl:$vKmpTorResource")
}

// GOOD! (non-gpl)
dependencies {
    implementation("io.matthewnelson.kmp-tor:resource-exec-tor:$vKmpTorResource")
    implementation("io.matthewnelson.kmp-tor:resource-noexec-tor:$vKmpTorResource")
}

// GOOD! (gpl)
dependencies {
    implementation("io.matthewnelson.kmp-tor:resource-exec-tor-gpl:$vKmpTorResource")
    implementation("io.matthewnelson.kmp-tor:resource-noexec-tor-gpl:$vKmpTorResource")
}

This is to respect the GPL licensed code tor is utilizing such that projects who have a GPL license are able to take advantage of the new functionality, and projects who do not have a GPL license can still utilize tor without infringing on the license.

Get Started

// build.gradle.kts
dependencies {
    val vKmpTorResource = "409.5.0"
    implementation("io.matthewnelson.kmp-tor:resource-exec-tor:$vKmpTorResource")
    implementation("io.matthewnelson.kmp-tor:resource-noexec-tor:$vKmpTorResource")

    // Alternatively, if wanting tor compiled with `--enable-gpl` (GPL v3 licensed code)
//    implementation("io.matthewnelson.kmp-tor:resource-exec-tor-gpl:$vKmpTorResource")
//    implementation("io.matthewnelson.kmp-tor:resource-noexec-tor-gpl:$vKmpTorResource")
}
Configure Android

Some additional configuration may be necessary for your Android application.

  • If utilizing the -exec Android dependency, tor compilations must be extracted to the ApplicationInfo.nativeLibraryDir when the application is installed:

    // build.gradle.kts
    android {
        packaging {
            jniLibs.useLegacyPackaging = true
        }
    }
    // gradle.properties
    android.bundle.enableUncompressedNativeLibs=false
  • If running unit tests for Android (not device/emulator), add the following dependency which will provide the desktop compilations and use them in lieu of the android compilations.

    // build.gradle.kts
    dependencies {
        testImplementation("io.matthewnelson.kmp-tor:resource-android-unit-test-tor:$vKmpTorResource")
    
        // Alternatively, if using the `-gpl` variants
    //    testImplementation("io.matthewnelson.kmp-tor:resource-android-unit-test-tor-gpl:$vKmpTorResource")
    }
  • Optionally, configure splits for each ABI:

    // build.gradle.kts
    android {
        splits {
            abi {
                isEnable = true
                reset()
                include("x86", "armeabi-v7a", "arm64-v8a", "x86_64")
                isUniversalApk = true
            }
        }
    }
Configure Android Native

Some additional configuration is necessary for your Android application. tor compilations are not shipped with the resource-exec-tor{-gpl} or resource-noexec-tor{-gpl} Android Native dependencies, they are packaged separately in an .aar and expected to be present at runtime.

  • If utilizing the resource-exec-tor{-gpl} Android Native dependency:

    • Add tor compilations to your Android application:
      // build.gradle.kts
      dependencies {
          implementation("io.matthewnelson.kmp-tor:resource-compilation-exec-tor:$vKmpTorResource")
      
          // Alternatively, if using the `-gpl` variants
      //    implementation("io.matthewnelson.kmp-tor:resource-compilation-exec-tor-gpl:$vKmpTorResource")
      }
    • The tor compilations must be extracted to the ApplicationInfo.nativeLibraryDir when the application is installed:
      // build.gradle.kts
      android {
          packaging {
              jniLibs.useLegacyPackaging = true
          }
      }
      // gradle.properties
      android.bundle.enableUncompressedNativeLibs=false
  • If utilizing the resource-noexec-tor{-gpl} Android Native dependency:

    • Add libtor compilations to your Android application:
      // build.gradle.kts
      dependencies {
          implementation("io.matthewnelson.kmp-tor:resource-compilation-lib-tor:$vKmpTorResource")
      
          // Alternatively, if using the `-gpl` variants
      //    implementation("io.matthewnelson.kmp-tor:resource-compilation-lib-tor-gpl:$vKmpTorResource")
      }
  • Optionally, configure splits for each ABI:

    // build.gradle.kts
    android {
        splits {
            abi {
                isEnable = true
                reset()
                include("x86", "armeabi-v7a", "arm64-v8a", "x86_64")
                isUniversalApk = true
            }
        }
    }
Configure iOS

See the frameworks gradle plugin README for more details.

Configure Jvm/Java

See the filterjar gradle plugin README for more details.

Configure Kotlin/Js and/or Kotlin/WasmJs

See the npmjs README for more details.

If utilizing with kmp-tor, simply pass into TorRuntime.Environment.Builder.

  • E.g. ResourceLoaderTorExec via resource-exec-tor dependency (or its -gpl variant)
val env = TorRuntime.Environment.Builder(myWorkDir, myCacheDir, ResourceLoaderTorExec::getOrCreate)
  • E.g. ResourceLoaderTorNoExec via resource-noexec-tor dependency (or its -gpl variant)
val env = TorRuntime.Environment.Builder(myWorkDir, myCacheDir, ResourceLoaderTorNoExec::getOrCreate)

See kmp-tor-samples for more details.

About

Tor resources for kmp-tor

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages