Reprodukowalne kompilacje zapewniają weryfikowalne powiązanie między opublikowanym kodem źródłowym a plikiem binarnym wydania. Nasz obecny zakres reprodukowalnych kompilacji obejmuje wydanie F-Droid dla systemu Android. Zamierzamy rozszerzyć ten zakres na dodatkowe kanały dystrybucji dla systemów Android i iOS.
Android
F-Droid
Gem Wallet korzysta z niezależnej infrastruktury kompilacji F-Droid, aby ponownie zbudować plik APK dla F-Droid i zweryfikować go przed publikacją.
Model weryfikacji
Gem Wallet publikuje podpisany plik APK dla F-Droid przy każdym wydaniu. Niezależnie od tego serwery kompilacji F-Droid wykonują publiczny przepis kompilacji w czystym środowisku:
- Metadane F-Droid wskazują dokładny commit Git oraz wersję Android NDK.
- F-Droid pobiera wskazany commit z publicznego repozytorium Gem Wallet.
- Publiczne skrypty reprodukowalnej kompilacji instalują przypięty natywny toolchain i uruchamiają
:app:assembleFdroidRelease. - Kompilacja generuje niepodpisany plik APK. F-Droid pobiera odpowiadający mu plik APK podpisany przez dewelopera i potwierdza, że jest on podpisany certyfikatem, którego odcisk zadeklarowano w
AllowedAPKSigningKeys. - F-Droid kopiuje podpis APK do ponownie zbudowanego artefaktu i weryfikuje go. Podpisy Android APK Signature Scheme v2/v3 obejmują cały plik APK poza blokiem podpisu, więc pomyślna weryfikacja wymaga, aby zawartość ponownie zbudowanego pliku APK była bajt po bajcie zgodna z wydaniem Gem Wallet.
- F-Droid publikuje plik APK podpisany przez dewelopera tylko wtedy, gdy weryfikacja zakończy się powodzeniem. Wydanie, którego nie udaje się odtworzyć, nie jest publikowane.
Mechanizmy deterministycznej kompilacji
Gem Wallet zawiera natywne biblioteki napisane w języku Rust, przez co wynik kompilacji jest wrażliwy na różnice w kompilatorze, linkerze, NDK, platformie hosta i optymalizatorze. Kompilacja F-Droid kontroluje te dane wejściowe poprzez:
- przypięcie wersji toolchainu Rust i
cargo-ndkwandroid/reproducible/versions.sh; - instalację
cargo-ndkz flagą--locked, podczas gdy zależności aplikacji w języku Rust są rozwiązywane na podstawie plikuCargo.lockz repozytorium; - przypięcie dokładnej rewizji Android NDK zarówno w projekcie Android, jak i w metadanych F-Droid;
- kompilację na hoście Linux
x86_64z jawnie określonymi ścieżkami do linkera i archiwizatora NDK; - ograniczenie natywnych architektur docelowych APK do
armeabi-v7aiarm64-v8a, niezależnie od hosta kompilacjix86_64; - użycie dedykowanego kanału produktowego
fdroid, bez modułów Google do powiadomień push i recenzji; - wyłączenie optymalizacji R8 za pomocą
-dontoptimize, aby zapobiec niedeterminizmowi w wyjściu DEX i identyfikatorach mapowania; - uruchamianie Gradle bez demona i pamięci podręcznej konfiguracji oraz czyszczenie pamięci podręcznych transformacji przed kompilacją wydania.
Dokładny commit źródłowy, polecenia kompilacji, ścieżka wyjściowa, rewizja NDK, adres URL oryginalnego pliku APK oraz dozwolony certyfikat podpisujący są publicznie dostępne w metadanych F-Droid. Skrypty konfigurujące Rust, Cargo, toolchain NDK i Gradle są utrzymywane razem z kodem źródłowym aplikacji w katalogu android/reproducible.
Właściwości bezpieczeństwa i ograniczenia
Pomyślna weryfikacja F-Droid dowodzi, że podpisany plik APK opublikowany przez Gem Wallet można odtworzyć z zadeklarowanego commita źródłowego i przepisu kompilacji. Ponowna kompilacja odbywa się poza infrastrukturą Gem Wallet, co zmniejsza zależność od naszego potoku wydań jako pojedynczego punktu zaufania.
Reprodukowalność nie dowodzi, że kod źródłowy jest wolny od podatności, że każda zależność jest godna zaufania ani że wybrany toolchain kompilatora nie został skompromitowany. Te ryzyka wymagają, oprócz reprodukowalnych kompilacji, przeglądu kodu źródłowego, kontroli zależności i zabezpieczenia toolchainu.
Status kompilacji i zweryfikowane wydania są dostępne na stronie Gem Wallet w katalogu F-Droid.
Universal APK i Google Play
Universal APK od Gem Wallet oraz wydanie w Google Play nie są obecnie objęte opisaną wyżej weryfikacją F-Droid. Obsługa reprodukowalnych kompilacji dla tych kanałów dystrybucji w systemie Android jest planowana w ramach przyszłych prac.
iOS
Wydanie w App Store nie jest obecnie reprodukowalne. Obsługa reprodukowalnych kompilacji dla iOS oraz niezależna weryfikacja pliku binarnego z App Store są planowane w ramach przyszłych prac.