From 8555a7a28227acbf49649e7c3323c3e18e40d7e6 Mon Sep 17 00:00:00 2001 From: ComplexSpaces Date: Sun, 3 Sep 2023 16:21:23 -0500 Subject: [PATCH 1/7] Prepare for repository conversion into a workspace --- android/rustls-platform-verifier/build.gradle | 2 +- Cargo.toml => rustls-platform-verifier/Cargo.toml | 0 rustls-platform-verifier/README.md | 1 + {src => rustls-platform-verifier/src}/android.rs | 0 {src => rustls-platform-verifier/src}/lib.rs | 0 {src => rustls-platform-verifier/src}/tests/ffi.rs | 0 {src => rustls-platform-verifier/src}/tests/mod.rs | 0 .../src}/tests/verification_mock/ca.go | 0 .../src}/tests/verification_mock/go.mod | 0 .../src}/tests/verification_mock/go.sum | 0 .../src}/tests/verification_mock/mod.rs | 0 .../verification_mock/root1-int1-ee_1-good.crt | Bin .../verification_mock/root1-int1-ee_1-good.ocsp | Bin .../verification_mock/root1-int1-ee_1-revoked.crt | Bin .../verification_mock/root1-int1-ee_1-revoked.ocsp | Bin .../verification_mock/root1-int1-ee_1-wrong_eku.crt | Bin .../root1-int1-ee_127.0.0.1-good.crt | Bin .../root1-int1-ee_127.0.0.1-good.ocsp | Bin .../root1-int1-ee_127.0.0.1-revoked.crt | Bin .../root1-int1-ee_127.0.0.1-revoked.ocsp | Bin .../root1-int1-ee_127.0.0.1-wrong_eku.crt | Bin .../root1-int1-ee_example.com-good.crt | Bin .../root1-int1-ee_example.com-good.ocsp | Bin .../root1-int1-ee_example.com-revoked.crt | Bin .../root1-int1-ee_example.com-revoked.ocsp | Bin .../root1-int1-ee_example.com-wrong_eku.crt | Bin .../src}/tests/verification_mock/root1-int1.crt | Bin .../src}/tests/verification_mock/root1.crt | Bin .../1password_com_valid_1.crt | Bin .../1password_com_valid_2.crt | Bin .../1password_com_valid_3.crt | Bin .../1password_com_valid_4.crt | Bin .../agilebits_com_valid_1.crt | Bin .../src}/tests/verification_real_world/mod.rs | 0 .../revoked_badssl_com_1.crt | Bin .../revoked_badssl_com_1.ocsp | Bin .../revoked_badssl_com_2.crt | Bin .../update_valid_1_cert.bash | 0 .../src}/verification/android.rs | 0 .../src}/verification/apple.rs | 0 .../src}/verification/mod.rs | 0 .../src}/verification/others.rs | 0 .../src}/verification/windows.rs | 0 {src => rustls-platform-verifier/src}/windows.rs | 0 44 files changed, 2 insertions(+), 1 deletion(-) rename Cargo.toml => rustls-platform-verifier/Cargo.toml (100%) create mode 120000 rustls-platform-verifier/README.md rename {src => rustls-platform-verifier/src}/android.rs (100%) rename {src => rustls-platform-verifier/src}/lib.rs (100%) rename {src => rustls-platform-verifier/src}/tests/ffi.rs (100%) rename {src => rustls-platform-verifier/src}/tests/mod.rs (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/ca.go (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/go.mod (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/go.sum (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/mod.rs (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/root1-int1-ee_1-good.crt (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/root1-int1-ee_1-good.ocsp (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/root1-int1-ee_1-revoked.crt (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/root1-int1-ee_1-revoked.ocsp (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/root1-int1-ee_1-wrong_eku.crt (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/root1-int1-ee_127.0.0.1-good.crt (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/root1-int1-ee_127.0.0.1-good.ocsp (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/root1-int1-ee_127.0.0.1-revoked.crt (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/root1-int1-ee_127.0.0.1-revoked.ocsp (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/root1-int1-ee_127.0.0.1-wrong_eku.crt (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/root1-int1-ee_example.com-good.crt (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/root1-int1-ee_example.com-good.ocsp (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/root1-int1-ee_example.com-revoked.crt (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/root1-int1-ee_example.com-revoked.ocsp (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/root1-int1-ee_example.com-wrong_eku.crt (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/root1-int1.crt (100%) rename {src => rustls-platform-verifier/src}/tests/verification_mock/root1.crt (100%) rename {src => rustls-platform-verifier/src}/tests/verification_real_world/1password_com_valid_1.crt (100%) rename {src => rustls-platform-verifier/src}/tests/verification_real_world/1password_com_valid_2.crt (100%) rename {src => rustls-platform-verifier/src}/tests/verification_real_world/1password_com_valid_3.crt (100%) rename {src => rustls-platform-verifier/src}/tests/verification_real_world/1password_com_valid_4.crt (100%) rename {src => rustls-platform-verifier/src}/tests/verification_real_world/agilebits_com_valid_1.crt (100%) rename {src => rustls-platform-verifier/src}/tests/verification_real_world/mod.rs (100%) rename {src => rustls-platform-verifier/src}/tests/verification_real_world/revoked_badssl_com_1.crt (100%) rename {src => rustls-platform-verifier/src}/tests/verification_real_world/revoked_badssl_com_1.ocsp (100%) rename {src => rustls-platform-verifier/src}/tests/verification_real_world/revoked_badssl_com_2.crt (100%) rename {src => rustls-platform-verifier/src}/tests/verification_real_world/update_valid_1_cert.bash (100%) rename {src => rustls-platform-verifier/src}/verification/android.rs (100%) rename {src => rustls-platform-verifier/src}/verification/apple.rs (100%) rename {src => rustls-platform-verifier/src}/verification/mod.rs (100%) rename {src => rustls-platform-verifier/src}/verification/others.rs (100%) rename {src => rustls-platform-verifier/src}/verification/windows.rs (100%) rename {src => rustls-platform-verifier/src}/windows.rs (100%) diff --git a/android/rustls-platform-verifier/build.gradle b/android/rustls-platform-verifier/build.gradle index c285d5ac..8171ef72 100644 --- a/android/rustls-platform-verifier/build.gradle +++ b/android/rustls-platform-verifier/build.gradle @@ -50,7 +50,7 @@ android { task buildTestLib(type: Exec) { workingDir "../../" - commandLine "cargo", "ndk", "-t", getOsArch(), "-o", "android/rustls-platform-verifier/src/androidTest/jniLibs", "build", "--features", "ffi-testing" + commandLine "cargo", "ndk", "-t", getOsArch(), "-o", "android/rustls-platform-verifier/src/androidTest/jniLibs", "build", "-p", "rustls-platform-verifier", "--features", "ffi-testing" } // Only compile the test library if this package is being built for testing by itself. diff --git a/Cargo.toml b/rustls-platform-verifier/Cargo.toml similarity index 100% rename from Cargo.toml rename to rustls-platform-verifier/Cargo.toml diff --git a/rustls-platform-verifier/README.md b/rustls-platform-verifier/README.md new file mode 120000 index 00000000..32d46ee8 --- /dev/null +++ b/rustls-platform-verifier/README.md @@ -0,0 +1 @@ +../README.md \ No newline at end of file diff --git a/src/android.rs b/rustls-platform-verifier/src/android.rs similarity index 100% rename from src/android.rs rename to rustls-platform-verifier/src/android.rs diff --git a/src/lib.rs b/rustls-platform-verifier/src/lib.rs similarity index 100% rename from src/lib.rs rename to rustls-platform-verifier/src/lib.rs diff --git a/src/tests/ffi.rs b/rustls-platform-verifier/src/tests/ffi.rs similarity index 100% rename from src/tests/ffi.rs rename to rustls-platform-verifier/src/tests/ffi.rs diff --git a/src/tests/mod.rs b/rustls-platform-verifier/src/tests/mod.rs similarity index 100% rename from src/tests/mod.rs rename to rustls-platform-verifier/src/tests/mod.rs diff --git a/src/tests/verification_mock/ca.go b/rustls-platform-verifier/src/tests/verification_mock/ca.go similarity index 100% rename from src/tests/verification_mock/ca.go rename to rustls-platform-verifier/src/tests/verification_mock/ca.go diff --git a/src/tests/verification_mock/go.mod b/rustls-platform-verifier/src/tests/verification_mock/go.mod similarity index 100% rename from src/tests/verification_mock/go.mod rename to rustls-platform-verifier/src/tests/verification_mock/go.mod diff --git a/src/tests/verification_mock/go.sum b/rustls-platform-verifier/src/tests/verification_mock/go.sum similarity index 100% rename from src/tests/verification_mock/go.sum rename to rustls-platform-verifier/src/tests/verification_mock/go.sum diff --git a/src/tests/verification_mock/mod.rs b/rustls-platform-verifier/src/tests/verification_mock/mod.rs similarity index 100% rename from src/tests/verification_mock/mod.rs rename to rustls-platform-verifier/src/tests/verification_mock/mod.rs diff --git a/src/tests/verification_mock/root1-int1-ee_1-good.crt b/rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_1-good.crt similarity index 100% rename from src/tests/verification_mock/root1-int1-ee_1-good.crt rename to rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_1-good.crt diff --git a/src/tests/verification_mock/root1-int1-ee_1-good.ocsp b/rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_1-good.ocsp similarity index 100% rename from src/tests/verification_mock/root1-int1-ee_1-good.ocsp rename to rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_1-good.ocsp diff --git a/src/tests/verification_mock/root1-int1-ee_1-revoked.crt b/rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_1-revoked.crt similarity index 100% rename from src/tests/verification_mock/root1-int1-ee_1-revoked.crt rename to rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_1-revoked.crt diff --git a/src/tests/verification_mock/root1-int1-ee_1-revoked.ocsp b/rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_1-revoked.ocsp similarity index 100% rename from src/tests/verification_mock/root1-int1-ee_1-revoked.ocsp rename to rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_1-revoked.ocsp diff --git a/src/tests/verification_mock/root1-int1-ee_1-wrong_eku.crt b/rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_1-wrong_eku.crt similarity index 100% rename from src/tests/verification_mock/root1-int1-ee_1-wrong_eku.crt rename to rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_1-wrong_eku.crt diff --git a/src/tests/verification_mock/root1-int1-ee_127.0.0.1-good.crt b/rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_127.0.0.1-good.crt similarity index 100% rename from src/tests/verification_mock/root1-int1-ee_127.0.0.1-good.crt rename to rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_127.0.0.1-good.crt diff --git a/src/tests/verification_mock/root1-int1-ee_127.0.0.1-good.ocsp b/rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_127.0.0.1-good.ocsp similarity index 100% rename from src/tests/verification_mock/root1-int1-ee_127.0.0.1-good.ocsp rename to rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_127.0.0.1-good.ocsp diff --git a/src/tests/verification_mock/root1-int1-ee_127.0.0.1-revoked.crt b/rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_127.0.0.1-revoked.crt similarity index 100% rename from src/tests/verification_mock/root1-int1-ee_127.0.0.1-revoked.crt rename to rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_127.0.0.1-revoked.crt diff --git a/src/tests/verification_mock/root1-int1-ee_127.0.0.1-revoked.ocsp b/rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_127.0.0.1-revoked.ocsp similarity index 100% rename from src/tests/verification_mock/root1-int1-ee_127.0.0.1-revoked.ocsp rename to rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_127.0.0.1-revoked.ocsp diff --git a/src/tests/verification_mock/root1-int1-ee_127.0.0.1-wrong_eku.crt b/rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_127.0.0.1-wrong_eku.crt similarity index 100% rename from src/tests/verification_mock/root1-int1-ee_127.0.0.1-wrong_eku.crt rename to rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_127.0.0.1-wrong_eku.crt diff --git a/src/tests/verification_mock/root1-int1-ee_example.com-good.crt b/rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_example.com-good.crt similarity index 100% rename from src/tests/verification_mock/root1-int1-ee_example.com-good.crt rename to rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_example.com-good.crt diff --git a/src/tests/verification_mock/root1-int1-ee_example.com-good.ocsp b/rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_example.com-good.ocsp similarity index 100% rename from src/tests/verification_mock/root1-int1-ee_example.com-good.ocsp rename to rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_example.com-good.ocsp diff --git a/src/tests/verification_mock/root1-int1-ee_example.com-revoked.crt b/rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_example.com-revoked.crt similarity index 100% rename from src/tests/verification_mock/root1-int1-ee_example.com-revoked.crt rename to rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_example.com-revoked.crt diff --git a/src/tests/verification_mock/root1-int1-ee_example.com-revoked.ocsp b/rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_example.com-revoked.ocsp similarity index 100% rename from src/tests/verification_mock/root1-int1-ee_example.com-revoked.ocsp rename to rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_example.com-revoked.ocsp diff --git a/src/tests/verification_mock/root1-int1-ee_example.com-wrong_eku.crt b/rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_example.com-wrong_eku.crt similarity index 100% rename from src/tests/verification_mock/root1-int1-ee_example.com-wrong_eku.crt rename to rustls-platform-verifier/src/tests/verification_mock/root1-int1-ee_example.com-wrong_eku.crt diff --git a/src/tests/verification_mock/root1-int1.crt b/rustls-platform-verifier/src/tests/verification_mock/root1-int1.crt similarity index 100% rename from src/tests/verification_mock/root1-int1.crt rename to rustls-platform-verifier/src/tests/verification_mock/root1-int1.crt diff --git a/src/tests/verification_mock/root1.crt b/rustls-platform-verifier/src/tests/verification_mock/root1.crt similarity index 100% rename from src/tests/verification_mock/root1.crt rename to rustls-platform-verifier/src/tests/verification_mock/root1.crt diff --git a/src/tests/verification_real_world/1password_com_valid_1.crt b/rustls-platform-verifier/src/tests/verification_real_world/1password_com_valid_1.crt similarity index 100% rename from src/tests/verification_real_world/1password_com_valid_1.crt rename to rustls-platform-verifier/src/tests/verification_real_world/1password_com_valid_1.crt diff --git a/src/tests/verification_real_world/1password_com_valid_2.crt b/rustls-platform-verifier/src/tests/verification_real_world/1password_com_valid_2.crt similarity index 100% rename from src/tests/verification_real_world/1password_com_valid_2.crt rename to rustls-platform-verifier/src/tests/verification_real_world/1password_com_valid_2.crt diff --git a/src/tests/verification_real_world/1password_com_valid_3.crt b/rustls-platform-verifier/src/tests/verification_real_world/1password_com_valid_3.crt similarity index 100% rename from src/tests/verification_real_world/1password_com_valid_3.crt rename to rustls-platform-verifier/src/tests/verification_real_world/1password_com_valid_3.crt diff --git a/src/tests/verification_real_world/1password_com_valid_4.crt b/rustls-platform-verifier/src/tests/verification_real_world/1password_com_valid_4.crt similarity index 100% rename from src/tests/verification_real_world/1password_com_valid_4.crt rename to rustls-platform-verifier/src/tests/verification_real_world/1password_com_valid_4.crt diff --git a/src/tests/verification_real_world/agilebits_com_valid_1.crt b/rustls-platform-verifier/src/tests/verification_real_world/agilebits_com_valid_1.crt similarity index 100% rename from src/tests/verification_real_world/agilebits_com_valid_1.crt rename to rustls-platform-verifier/src/tests/verification_real_world/agilebits_com_valid_1.crt diff --git a/src/tests/verification_real_world/mod.rs b/rustls-platform-verifier/src/tests/verification_real_world/mod.rs similarity index 100% rename from src/tests/verification_real_world/mod.rs rename to rustls-platform-verifier/src/tests/verification_real_world/mod.rs diff --git a/src/tests/verification_real_world/revoked_badssl_com_1.crt b/rustls-platform-verifier/src/tests/verification_real_world/revoked_badssl_com_1.crt similarity index 100% rename from src/tests/verification_real_world/revoked_badssl_com_1.crt rename to rustls-platform-verifier/src/tests/verification_real_world/revoked_badssl_com_1.crt diff --git a/src/tests/verification_real_world/revoked_badssl_com_1.ocsp b/rustls-platform-verifier/src/tests/verification_real_world/revoked_badssl_com_1.ocsp similarity index 100% rename from src/tests/verification_real_world/revoked_badssl_com_1.ocsp rename to rustls-platform-verifier/src/tests/verification_real_world/revoked_badssl_com_1.ocsp diff --git a/src/tests/verification_real_world/revoked_badssl_com_2.crt b/rustls-platform-verifier/src/tests/verification_real_world/revoked_badssl_com_2.crt similarity index 100% rename from src/tests/verification_real_world/revoked_badssl_com_2.crt rename to rustls-platform-verifier/src/tests/verification_real_world/revoked_badssl_com_2.crt diff --git a/src/tests/verification_real_world/update_valid_1_cert.bash b/rustls-platform-verifier/src/tests/verification_real_world/update_valid_1_cert.bash similarity index 100% rename from src/tests/verification_real_world/update_valid_1_cert.bash rename to rustls-platform-verifier/src/tests/verification_real_world/update_valid_1_cert.bash diff --git a/src/verification/android.rs b/rustls-platform-verifier/src/verification/android.rs similarity index 100% rename from src/verification/android.rs rename to rustls-platform-verifier/src/verification/android.rs diff --git a/src/verification/apple.rs b/rustls-platform-verifier/src/verification/apple.rs similarity index 100% rename from src/verification/apple.rs rename to rustls-platform-verifier/src/verification/apple.rs diff --git a/src/verification/mod.rs b/rustls-platform-verifier/src/verification/mod.rs similarity index 100% rename from src/verification/mod.rs rename to rustls-platform-verifier/src/verification/mod.rs diff --git a/src/verification/others.rs b/rustls-platform-verifier/src/verification/others.rs similarity index 100% rename from src/verification/others.rs rename to rustls-platform-verifier/src/verification/others.rs diff --git a/src/verification/windows.rs b/rustls-platform-verifier/src/verification/windows.rs similarity index 100% rename from src/verification/windows.rs rename to rustls-platform-verifier/src/verification/windows.rs diff --git a/src/windows.rs b/rustls-platform-verifier/src/windows.rs similarity index 100% rename from src/windows.rs rename to rustls-platform-verifier/src/windows.rs From 25041d11fdc11cb9acc16feaceeb7e17c9486dd4 Mon Sep 17 00:00:00 2001 From: ComplexSpaces Date: Fri, 8 Sep 2023 22:31:30 -0500 Subject: [PATCH 2/7] Introduce new Cargo workspace --- Cargo.toml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Cargo.toml diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 00000000..11a96577 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,4 @@ +[workspace] +members = ["rustls-platform-verifier"] + +resolver = "2" From 1d99e9bcde7c045250ef1c57f2ac0f1af5e7f098 Mon Sep 17 00:00:00 2001 From: ComplexSpaces Date: Fri, 8 Sep 2023 02:48:17 -0500 Subject: [PATCH 3/7] Add note about possible issues due to Proguard optimizing out the Android component --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index c3626b0e..635dd291 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,13 @@ successfully, resulting in a `rustls` group appearing in Android Studio's projec After this, everything should be ready to use. Future updates of `rustls-platform-verifier` won't need any maintenance beyond the expected `cargo update`. +If your Android application makes use of Proguard for optimizations, its important to make sure that the Android verifier component isn't optimized +out because it looks like dead code. Proguard is unable to see any JNI usage, so your rules must manually opt into keeping it. THe following rule +can do this for you: +```text +-keep, includedescriptorclasses class org.rustls.platformverifier.** { *; } +``` + #### Crate initialization In order for the crate to call into the JVM, it needs handles from Android. These From 71a58d080c705b23b7cbdcbc4be25f9a46b0f9c3 Mon Sep 17 00:00:00 2001 From: ComplexSpaces Date: Fri, 8 Sep 2023 02:05:08 -0500 Subject: [PATCH 4/7] Distribute Android component through pre-built Maven local repository --- .gitignore | 5 ++ Cargo.lock | 5 ++ Cargo.toml | 5 +- README.md | 74 +++++++++---------- admin/RELEASING.md | 18 +++++ android-release-support/Cargo.toml | 18 +++++ .../rustls/rustls-platform-verifier/.gitkeep | 0 android-release-support/pom-template.xml | 10 +++ android-release-support/src/lib.rs | 71 ++++++++++++++++++ android/settings.gradle | 12 +-- ci/package_android_release.sh | 38 ++++++++++ rustls-platform-verifier/Cargo.toml | 9 +-- 12 files changed, 204 insertions(+), 61 deletions(-) create mode 100644 admin/RELEASING.md create mode 100644 android-release-support/Cargo.toml create mode 100644 android-release-support/maven/rustls/rustls-platform-verifier/.gitkeep create mode 100644 android-release-support/pom-template.xml create mode 100644 android-release-support/src/lib.rs create mode 100755 ci/package_android_release.sh diff --git a/.gitignore b/.gitignore index 5823b44e..988879bd 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,8 @@ /.idea /android/verification/ + +# Ignore all generated Maven local repository files and folders +/android-release-support/maven/pom.xml +/android-release-support/maven/rustls/rustls-platform-verifier/**/ +/android-release-support/maven/rustls/rustls-platform-verifier/maven-metadata-local.xml \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 4d85db0d..3ed7b091 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -668,6 +668,7 @@ dependencies = [ "reqwest", "rustls", "rustls-native-certs", + "rustls-platform-verifier-android", "rustls-webpki", "security-framework", "security-framework-sys", @@ -676,6 +677,10 @@ dependencies = [ "winapi", ] +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.0" + [[package]] name = "rustls-webpki" version = "0.101.4" diff --git a/Cargo.toml b/Cargo.toml index 11a96577..c29f147e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,7 @@ [workspace] -members = ["rustls-platform-verifier"] +members = [ + "android-release-support", + "rustls-platform-verifier", +] resolver = "2" diff --git a/README.md b/README.md index 635dd291..c287d2a1 100644 --- a/README.md +++ b/README.md @@ -49,57 +49,49 @@ component must be included in your app's build to support `rustls-platform-verif `rustls-platform-verifier` bundles the required native components in the crate, but the project must be setup to locate them automatically and correctly. -Firstly, create an [init script](https://docs.gradle.org/current/userguide/init_scripts.html) in your Android -Gradle project, with a filename of `init.gradle`. This is generally placed in your project's root. In your project's `settings.gradle`, add these lines: +Inside of your project's `build.gradle` file, add the following code and Maven repository definition. `$PATH_TO_DEPENDENT_CRATE` is +the relative path to the Cargo manifest (`Cargo.toml`) of any crate in your workspace that depends on `rustls-platform-verifier` from +the location of your `build.gradle` file: ```groovy -apply from: file("./init.gradle"); -// Cargo automatically handles finding the downloaded crate in the correct location -// for your project. -def veifierProjectPath = findRustlsPlatformVerifierProject() -includeBuild("${verifierProjectPath}/android/") -``` - -Next, the `rustls-platform-verifier` external dependency needs to be setup. Open the `init.gradle` file and add the following: -`$PATH_TO_DEPENDENT_CRATE` is the relative path to the Cargo manifest (`Cargo.toml`) of any crate in your workspace that depends on `rustls-platform-verifier` -from the location of your `init.gradle` file. - -Alternatively, you can use `cmdProcessBuilder.directory(File("PATH_TO_ROOT"))` to change the working directory instead. - -```groovy -ext.findRustlsPlatformVerifierProject = { - def cmdProcessBuilder = new ProcessBuilder(new String[] { "cargo", "metadata", "--format-version", "1", "--manifest-path", "$PATH_TO_DEPENDENT_CRATE" }) - def dependencyInfoText = new StringBuffer() +import groovy.json.JsonSlurper +import groovy.transform.Memoized + +// ...Your own script code could be here... + +allprojects { + repositories { + // ... Your other repositories could be here... + maven { + url = findRustlsPlatformVerifierProject() + metadataSources.artifact() + } + } +} - def cmdProcess = cmdProcessBuilder.start() - cmdProcess.consumeProcessOutput(dependencyInfoText, null) - cmdProcess.waitFor() +@Memoized +String findRustlsPlatformVerifierProject() { + def dependencyText = providers.exec { + it.workingDir = new File("../") + commandLine("cargo", "metadata", "--format-version", "1", "--manifest-path", "$PATH_TO_DEPENDENT_CRATE/Cargo.toml") + }.standardOutput.asText.get() - def dependencyJson = new groovy.json.JsonSlurper().parseText(dependencyInfoText.toString()) - def manifestPath = file(dependencyJson.packages.find { it.name == "rustls-platform-verifier" }.manifest_path) - return manifestPath.parent + def dependencyJson = new JsonSlurper().parseText(dependencyText) + def manifestPath = file(dependencyJson.packages.find { it.name == "rustls-platform-verifier-android" }.manifest_path) + return new File(manifestPath.parentFile, "maven").path } ``` -This script can be tweaked as best suits your project, but the `cargo metadata` invocation must be included so that the Android -implementation source can be located on disk. - -If your project often updates its Android Gradle Plugin versions, you should additionally consider setting your app's project -up to override `rustls-platform-verifier`'s dependency versions. This allows your app to control what versions are used and avoid -conflicts. To do so, advertise a `versions.path` system property from your `settings.gradle`: - +Then, wherever you declare your dependencies, add the following: ```groovy -ext.setVersionsPath = { - System.setProperty("versions.path", file("your/versions/path.toml").absolutePath) -} - -setVersionsPath() +implementation "rustls:rustls-platform-verifier:latest.release" ``` -Finally, sync your gradle project changes. It should pick up on the `rustls-platform-verifier` Gradle project. It should finish -successfully, resulting in a `rustls` group appearing in Android Studio's project view. -After this, everything should be ready to use. Future updates of `rustls-platform-verifier` won't need any maintenance beyond the -expected `cargo update`. +Cargo automatically handles finding the downloaded crate in the correct location for your project. It also handles updating the version when +new releases of `rustls-platform-verifier` are published. If you only use published releases, no extra maintainence should be required. + +These script snippets can be tweaked as best suits your project, but the `cargo metadata` invocation must be included so that the Android +implementation part can be located on disk. If your Android application makes use of Proguard for optimizations, its important to make sure that the Android verifier component isn't optimized out because it looks like dead code. Proguard is unable to see any JNI usage, so your rules must manually opt into keeping it. THe following rule diff --git a/admin/RELEASING.md b/admin/RELEASING.md new file mode 100644 index 00000000..8d80a090 --- /dev/null +++ b/admin/RELEASING.md @@ -0,0 +1,18 @@ +# How-to release `rustls-platform-verifier` + +This document records the steps to publish new versions of the crate since it requires non-trivial preperation and ordering +that needs to be remembered due to the Android component's distribution. + +## Steps + +1. Update main crate'a version in `rustls-platform-verifier/Cargo.toml`, and in any additional places. +2. If any non-test changes have been made to the `android` directory since the last release: + 1. Update Android artifact version in `android-release-support/Cargo.toml` + 2. Bump dependency version of the Android support crate in `rustls-platform-verifier/Cargo.toml` to match the new one + 3. Commit version increase changes on the release branch + 4. Run `ci/package_android_release.sh` in a UNIX compatible shell + 5. (Optional) `cargo publish -p rustls-platform-verifier-android --dry-run` + 6. (Optional) Inspect extracted archive to ensure the local Maven repository artifacts are present + 7. Publish the Android artifacts' new version: `cargo publish -p rustls-platform-verifier-android` +3. Commit main crate's version increase on the release branch +4. Publish the main crate's new version: `cargo publish -p rustls-platform-verifier` diff --git a/android-release-support/Cargo.toml b/android-release-support/Cargo.toml new file mode 100644 index 00000000..0dae8995 --- /dev/null +++ b/android-release-support/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "rustls-platform-verifier-android" +version = "0.1.0" +description = "The internal JVM support component of the rustls-platform-verifier crate. You shouldn't depend on this directly." +repository = "https://github.com/1Password/rustls-platform-verifier" +license = "MIT OR Apache-2.0" +edition = "2021" + +# Explicitly include the Maven local repository for the Android component. +# While not checked into the repository, it is generated for releases and other contexts. +include = [ + "src/*", + "maven/pom.xml", + "maven/rustls/rustls-platform-verifier/**/", + "maven/rustls/rustls-platform-verifier/maven-metadata-local.xml", +] + +[dependencies] diff --git a/android-release-support/maven/rustls/rustls-platform-verifier/.gitkeep b/android-release-support/maven/rustls/rustls-platform-verifier/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/android-release-support/pom-template.xml b/android-release-support/pom-template.xml new file mode 100644 index 00000000..cbc86eb9 --- /dev/null +++ b/android-release-support/pom-template.xml @@ -0,0 +1,10 @@ + + + 4.0.0 + rustls + rustls-platform-verifier + $VERSION + aar + The internal JVM support component of the rustls-platform-verifier Rust crate + \ No newline at end of file diff --git a/android-release-support/src/lib.rs b/android-release-support/src/lib.rs new file mode 100644 index 00000000..d6d3aef2 --- /dev/null +++ b/android-release-support/src/lib.rs @@ -0,0 +1,71 @@ +//! # rustls-platform-verifier-android +//! +//! This crate is an implementation detail of the actual [rustls-platform-verifier](https://github.com/rustls/rustls-platform-verifier) crate. +//! +//! It contains no Rust code and is solely intended as a convenient delivery mechanism for the supporting Kotlin code that the main crate +//! requires to perform TLS certificate validation using Android's APIs. +//! +//! Other crates should not directly depend on this crate in any way, as nothing about it is considered stable and probably useless elsewhere. +//! +//! ## Details +//! +//! Note: Everything in this section is subject to change at any time. Semver may not be followed either. +//! +//! ### Why? +//! +//! It was the best middle ground between several tradeoffs. The important ones, in priority order, are: +//! - Automatically keeping component versions in sync +//! - Allowing well-tested and well-known `cargo` dependency management patterns to apply everywhere +//! - Providing a smooth developer experience as an Android consumer of `rustls-platform-verifier` +//! +//! Firstly, what alternatives are available for distributing the component? The other two known are source distribution n some form (here, it will be through crates.io) +//! and Maven Central. Starting with the first, its become infeasible due to toolchain syncing requirements. If the Android component is +//! built as part of the host app's Gradle build, then it becomes subject to any Gradle or AGP incompatibilites/requirements. In practice this means +//! the AGP version between this project and the main application have to match all the time. Sometimes this works, but it becomes challenging/unfeasible +//! during yearly toolchain/SDK upgrades and is not maintainable long term. Note that this is the _only_ option in this section which retains compatible +//! with Cargo's Git dependency patching. +//! +//! Next, Maven Central. This is considered the standard way of distributing public Android dependencies. There are two downsides to this +//! approach: version synchronization and publishing overhead. Version syncing is the hardest part: There's not a good way to know what version +//! a crate is that doesn't hurt the Cargo part of the build or damage functionality. So instead of making assumptions at runtime, we would need to do +//! clunky and manual version counting with an extra error case. Less importantly, the admin overhead of Maven Central is non-zero so its good to avoid +//! if possible for such a small need. +//! +//! It is also worth calling out a third set of much worse options: requiring users to manually download and install the Android component +//! on each update, which magnifies the version syncing problem with lots of user overhead and then deleting the component outright. A rewrite +//! could be done with raw JNI calls, but this would easily be 3x the size of the existing implementation and require huge amounts of `unsafe` +//! to review then audit. +//! +//! ### The solution +//! +//! The final design was built to avoid the pitfalls the previous two options mentioned. To build it, we rely on CI and packaging scripts to build +//! the Android component into a prebuilt AAR file before creating a release. Next, a [on-disk Maven repository](https://maven.apache.org/repositories/local.html) +//! is hosted inside of this repository. Only the unchanging file structure of it is kept checked-in, to avoid churn. The remaining parts are filled in +//! during the packaging/release process, before being included in `cargo package` via an `include` Cargo.toml directive. Finally, once the repository has had +//! its artifacts added, this crate is published to crates.io containing it. Then, the main crate ensures its downloaded when an Android target is compiled for via +//! a platform-specific dependency. +//! +//! On the Gradle side, we include a very small snippet of code for users to include in their `settings.gradle` file to dyanmically locate the local maven repository +//! on disk automatically based off Cargo's current version of it. The script is configuration cache friendly and doesn't impact performance either. When the script +//! is run, it finds the cargo-cached download of the crate and tells Gradle it can find the `rustls-platform-verifier` Android component there when it gets sourced +//! into the hosting application's build tree. +//! +//! ### Precompiled artifacts? +//! +//! For some, the notion of shipping something pre-compiled with an existing source distribution might seem incorrect, or insecure. However in this specific case, +//! putting aside the fact shipping Kotlin code doesn't work (see above), there are many reasons this isn't the case: +//! - Shipping pre-compiled artifacts is normal in the Java ecosystem. Maven Central and other package repositories do the same thing and serve `.jar` downloads. +//! - Those not using Android will never download the pre-compiled AAR file. +//! - The artifacts are incredibly easy to reproduce given an identicial compilation toolchain. +//! - The artifacts are not native executables, or raw `.jar` files, so they can't be accidentally executed on a host system. +//! +//! ## Summary +//! +//! In summary, the selected distribution method avoids most of the previous pitfalls while still balancing a good experience for `cargo` annd Gradle users. Some of its +//! positive properties include: +//! - Full compatibility with Cargo's dependency management, including Git patching[^1] +//! - No version checking or synchronization required +//! - Painless and harmless to integrate into an Android app's build system +//! - Low maintenance for the main crate maintainers' +//! +//! [^1]: The Git reference being used must have the local maven repository built and checked-in first. diff --git a/android/settings.gradle b/android/settings.gradle index e4416705..e00d83fe 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -12,19 +12,9 @@ dependencyResolutionManagement { mavenCentral() } - // We use a version catalog for two reasons: - // 1. Ease of dependency management - // 2. Supporting having our versions overridden by a larger project including us - // as a composite build. This lets versions stay in sync when they would otherwise become - // incompatible. Examples of this include AGP, where an actual app might have a newer one - // then this library (which doesn't need to). - // - // This works by first trying to read global property that a parent module could advertise - // and then falling back to our local definitions. In combination, both project-local tasks - // still work as intended and use as a library in a full application. versionCatalogs { libs { - from(files(System.getProperty("versions.path", "gradle/libraries.versions.toml"))) + from(files("gradle/libraries.versions.toml")) } } } diff --git a/ci/package_android_release.sh b/ci/package_android_release.sh new file mode 100755 index 00000000..d4d4d946 --- /dev/null +++ b/ci/package_android_release.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +# This script's purpose is to automate the build + packaging steps for the pre-compiled Android verifier component. +# It works with template files and directories inside the `android-release-support/` part of the repository to setup +# a Maven local repository and then add the pre-compiled AAR file into it for distribution. The results of this packaging +# are then included by `cargo` when publishing `rustls-platform-verifier-android`. + +set -euo pipefail + +if ! type mvn > /dev/null; then + echo "The maven CLI, mvn, is required to run this script." + echo "Download it from: https://maven.apache.org/download.cgi" + exit 1 +fi + +version=$(cat android-release-support/Cargo.toml | grep -m 1 "version = " | tr -d "version= " | tr -d '"') + +echo "Packaging v$version of the Android support component" + +pushd ./android + +./gradlew assembleRelease + +popd + +artifact_name="rustls-platform-verifier-release.aar" + +pushd ./android-release-support + +artifact_path="../android/rustls-platform-verifier/build/outputs/aar/$artifact_name" + +# Ensure no prior artifacts are present +git clean -dfX "./maven/" + +cp ./pom-template.xml ./maven/pom.xml +sed -i "" "s/\$VERSION/$version/" ./maven/pom.xml + +mvn install:install-file -Dfile="$artifact_path" -Dpackaging="aar" -DpomFile="./maven/pom.xml" -DlocalRepositoryPath="./maven/" diff --git a/rustls-platform-verifier/Cargo.toml b/rustls-platform-verifier/Cargo.toml index 09d2378e..631683b9 100644 --- a/rustls-platform-verifier/Cargo.toml +++ b/rustls-platform-verifier/Cargo.toml @@ -9,14 +9,6 @@ license = "MIT OR Apache-2.0" edition = "2021" rust-version = "1.64.0" -exclude = [ - "android/.run", - "android/gradle/**", - "android/gradle*", - "android/settings.gradle", - "android/src/androidTest", -] - [lib] name = "rustls_platform_verifier" # Note: The `cdylib` specification is for testing only. The shared library @@ -49,6 +41,7 @@ once_cell = "1.9" webpki = { package = "rustls-webpki", version = "0.101", features = ["alloc", "std"] } [target.'cfg(target_os = "android")'.dependencies] +rustls-platform-verifier-android = { path = "../android-release-support", version = "0.1.0" } jni = { version = "0.19", default-features = false } webpki = { package = "rustls-webpki", version = "0.101", features = ["alloc", "std"] } once_cell = "1.9" From 9818850119c5549bf1ff196deab43952532bb326 Mon Sep 17 00:00:00 2001 From: ComplexSpaces Date: Sat, 9 Sep 2023 01:19:00 -0500 Subject: [PATCH 5/7] Validate gradle wrapper binaries in CI --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ec17adce..c1defdbc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -196,6 +196,10 @@ jobs: - uses: actions/checkout@v3 with: persist-credentials: false + + # Ensure only legitimate Gradle wrapper binaries can be merged into `main` + - name: Validate Gradle Wrappers + uses: gradle/wrapper-validation-action@56b90f209b02bf6d1deae490e9ef18b21a389cd4 # 1.1.0 - name: Verify release artifact run: ./ci/verify_android_release.sh From 036ac7e77ae6167396f3a12c770a77e171261a7c Mon Sep 17 00:00:00 2001 From: ComplexSpaces Date: Fri, 8 Sep 2023 23:13:22 -0500 Subject: [PATCH 6/7] WIP: Automated Android branch builds --- .github/workflows/android_builds.yml | 52 ++++++++++++++++++++++++++++ .github/workflows/ci.yml | 8 ++--- ci/package_android_release.sh | 7 +++- 3 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/android_builds.yml diff --git a/.github/workflows/android_builds.yml b/.github/workflows/android_builds.yml new file mode 100644 index 00000000..fd7aff90 --- /dev/null +++ b/.github/workflows/android_builds.yml @@ -0,0 +1,52 @@ +on: + pull_request: + branches: + - main + # types: + # - closed + +name: Update Android Artifacts + +permissions: + contents: write + +jobs: + update-android-branch: + # if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Setup Java + uses: actions/setup-java@v3 + with: + java-version: "17" + distribution: "temurin" + + - name: Validate Gradle Wrappers + uses: gradle/wrapper-validation-action@56b90f209b02bf6d1deae490e9ef18b21a389cd4 # 1.1.0 + + # Configure a committer identity and obtain information + # about the `main-with-maven` branch. + - name: Configure Git + run: | + git config --global user.name "Android Builder" + git config --global user.email "buildbot@rustls.org" + git fetch --all + + # Build up the same Maven local repository that would be used for + # a crates.io release and commit it to the dedicated Android branch. + - name: Package Android AAR + run: | + echo "Syncing main branch state to the Maven hosting branch" + git checkout -b main-with-maven + # git reset --hard origin/main + git reset --hard origin/automated-android-branch + + echo "Building new Android release from main" + ./ci/package_android_release.sh + + git add --force android-release-support/* + git commit -am "[Automated] Bundle Android component artifacts" + # git push -f origin main-with-maven + git push -f origin HEAD:main-with-maven diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c1defdbc..5db2c7e3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,10 +3,10 @@ on: branches: - main - "*_dev" - pull_request: - merge_group: - schedule: - - cron: '0 18 * * *' + #pull_request: + # merge_group: + #schedule: + # - cron: '0 18 * * *' name: CI permissions: diff --git a/ci/package_android_release.sh b/ci/package_android_release.sh index d4d4d946..2dea5595 100755 --- a/ci/package_android_release.sh +++ b/ci/package_android_release.sh @@ -33,6 +33,11 @@ artifact_path="../android/rustls-platform-verifier/build/outputs/aar/$artifact_n git clean -dfX "./maven/" cp ./pom-template.xml ./maven/pom.xml -sed -i "" "s/\$VERSION/$version/" ./maven/pom.xml + +# This sequence is meant to workaround the incompatibilites between macOS's sed +# command and the GNU command. Referenced from the following: +# https://stackoverflow.com/questions/5694228/sed-in-place-flag-that-works-both-on-mac-bsd-and-linux +sed -i.bak "s/\$VERSION/$version/" ./maven/pom.xml +rm ./maven/pom.xml.bak mvn install:install-file -Dfile="$artifact_path" -Dpackaging="aar" -DpomFile="./maven/pom.xml" -DlocalRepositoryPath="./maven/" From e147cb2e6eddb99d17afef93558d02003ccbfe7d Mon Sep 17 00:00:00 2001 From: ComplexSpaces Date: Sat, 9 Sep 2023 11:34:47 -0500 Subject: [PATCH 7/7] Test custom branch protection rules --- .github/workflows/android_builds.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/android_builds.yml b/.github/workflows/android_builds.yml index fd7aff90..f3524b23 100644 --- a/.github/workflows/android_builds.yml +++ b/.github/workflows/android_builds.yml @@ -49,4 +49,4 @@ jobs: git add --force android-release-support/* git commit -am "[Automated] Bundle Android component artifacts" # git push -f origin main-with-maven - git push -f origin HEAD:main-with-maven + git push -f origin HEAD:testing-branch-permissions