Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 3 additions & 18 deletions modules/apps/prebuilt.nix
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,6 @@ let
include $(BUILD_PREBUILT)
'');

build-tools =
(pkgs.androidPkgs.sdk (p: with p.stable; [ tools build-tools-30-0-2 ]))
+ "/share/android-sdk/build-tools/30.0.2";

apksigner = pkgs.runCommand "apksigner" { nativeBuildInputs = [ pkgs.makeWrapper ]; } ''
mkdir -p $out/bin
makeWrapper "${pkgs.jre8_headless}/bin/java" "$out/bin/apksigner" \
--add-flags "-jar ${build-tools}/lib/apksigner.jar"
'';

signApk = {name, apk, keyPath}: pkgs.runCommand "${name}-signed.apk" { nativeBuildInputs = [ pkgs.jre8_headless ]; } ''
cp ${apk} $out
${apksigner}/bin/apksigner sign --key ${keyPath}.pk8 --cert ${keyPath}.x509.pem $out
'';

# TODO: Uses IFD. Try to avoid using this.
apkFingerprint = apk: (import pkgs.runCommand "apk-fingerprint" { nativeBuildInputs = [ pkgs.jre8_headless ]; } ''
fingerprint=$(keytool -printcert -jarfile ${apk} | grep "SHA256:" | tr --delete ':' | cut --delimiter ' ' --fields 3)
Expand Down Expand Up @@ -139,8 +124,8 @@ in

# Uses the sandbox exception in /keys
signedApk = mkDefault (
if config.certificate == "PRESIGNED" then config.apk else (signApk {
inherit (config) name apk;
if config.certificate == "PRESIGNED" then config.apk else (pkgs.signApk {
inherit (config) apk;
keyPath = _config.build.sandboxKeyPath config.certificate;
}));

Expand Down Expand Up @@ -172,7 +157,7 @@ in

### Check minSdkVersion, targetSdkVersion
# TODO: Also check permissions?
MANIFEST_DUMP=$(${build-tools}/aapt2 d xmltree --file AndroidManifest.xml ${apk})
MANIFEST_DUMP=$(${pkgs.build-tools}/aapt2 d xmltree --file AndroidManifest.xml ${apk})

# It would be better if we could convert it back into true XML and then select based on XPath
MIN_SDK_VERSION=$(echo "$MANIFEST_DUMP" | grep minSdkVersion | cut -d= -f2)
Expand Down
45 changes: 33 additions & 12 deletions modules/google.nix
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ in
config_priorityOnlyDndExemptPackages = [ "com.google.android.dialer" ]; # Found under PixelConfigOverlayCommon.apk
};
apps.prebuilt.GoogleDialer = {
apk = "${productPath}/priv-app/GoogleDialer/GoogleDialer.apk";
apk = pkgs.verifyApk {
apk = "${productPath}/priv-app/GoogleDialer/GoogleDialer.apk";
sha256 = "e2d049f3a01192f620b1240615fa8c13badc553c22bc6fddfca45c84d8fc545d";
};
privileged = true;
certificate = "PRESIGNED";
};
Expand All @@ -77,40 +80,58 @@ in
google.base.enable = true;
google.dialer.enable = true;
apps.prebuilt = {
Tycho = {
apk = "${productPath}/app/Tycho/Tycho.apk"; # Google Fi app
Tycho = { # Google Fi app
apk = pkgs.verifyApk {
apk = "${productPath}/app/Tycho/Tycho.apk";
sha256 = "4c36af4a5bdad97c1f3d8b283416d244496c2ac5eafe8226079ef6f676fd1859";
};
certificate = "PRESIGNED";
};
GCS = {
apk = "${productPath}/priv-app/GCS/GCS.apk"; # Google Connectivity Services (does wifi VPN at least)
GCS = { # Google Connectivity Services (does wifi VPN at least)
apk = pkgs.verifyApk {
apk = "${productPath}/priv-app/GCS/GCS.apk";
sha256 = "8efed9b84a6320eafde625cea7bb6bae0e320473d0e3c04fb0cd43b779078e1d";
};
certificate = "PRESIGNED";
privileged = true;
};
#### Disabling for now, since calls aren't working ####
# CarrierServices = {
# apk = "${productPath}/priv-app/CarrierServices/CarrierServices.apk"; # Google Carrier Services. com.google.android.ims (needed for wifi calls)
# apk = pkgs.verifyApk {
# apk = "${productPath}/priv-app/CarrierServices/CarrierServices.apk"; # Google Carrier Services. com.google.android.ims (needed for wifi calls)
# sha256 = "c25d5afacb6783109d6136d79353fad4f6541c3545d25228a18703d043ca783f";
# };
# certificate = "PRESIGNED";
# privileged = true;
# };
CarrierSettings = {
apk = "${productPath}/priv-app/CarrierSettings/CarrierSettings.apk"; # com.google.android.carrier
CarrierSettings = { # com.google.android.carrier
apk = pkgs.verifyApk {
apk = "${productPath}/priv-app/CarrierSettings/CarrierSettings.apk";
sha256 = "383d1e1b525ec6fb8204c5bf9b8390d37fd157e78b8b7212d61487b178066d20";
};
certificate = "PRESIGNED";
privileged = true;
};
CarrierSetup = {
apk = "${systemExtPath}/priv-app/CarrierSetup/CarrierSetup.apk"; # com.google.android.carriersetup
CarrierSetup = { # com.google.android.carriersetup
apk = "${systemExtPath}/priv-app/CarrierSetup/CarrierSetup.apk"; # Uses device-specific keys
certificate = "PRESIGNED";
privileged = true;
};
} // (optionalAttrs (config.deviceFamily == "crosshatch") { # TODO: Generalize to other devices with esim
EuiccGoogle = {
apk = "${productPath}/priv-app/EuiccGoogle/EuiccGoogle.apk";
apk = pkgs.verifyApk {
apk = "${productPath}/priv-app/EuiccGoogle/EuiccGoogle.apk";
sha256 = "7e26b6d5802a16799448ad635868f0345d6730310634684c0ae44e7e9f7ea764";
};
certificate = "PRESIGNED";
privileged = true;
};
}) // (optionalAttrs ((config.deviceFamily == "crosshatch") && (config.androidVersion >= 10)) {
EuiccSupportPixel = {
apk = "${productPath}/priv-app/EuiccSupportPixel/EuiccSupportPixel.apk";
apk = pkgs.verifyApk {
apk = "${productPath}/priv-app/EuiccSupportPixel/EuiccSupportPixel.apk";
sha256 = "e0afeca77af15aee48a25ead314c576f8f274682a8fba3365610878f7c1ddb6b";
};
certificate = "PRESIGNED";
privileged = true;
};
Expand Down
16 changes: 10 additions & 6 deletions modules/microg.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ with lib;

let
version = "0.2.13.203915";
verifyApk = apk: pkgs.verifyApk {
inherit apk;
sha256 = "9bd06727e62796c0130eb6dab39b73157451582cbd138e86c468acc395d14165"; # O=NOGAPPS Project, C=DE
};
in
{
options = {
Expand All @@ -27,27 +31,27 @@ in
# Used https://github.com/lineageos4microg/android_prebuilts_prebuiltapks as source for Android.mk options
apps.prebuilt = {
GmsCore = {
apk = pkgs.fetchurl {
apk = verifyApk (pkgs.fetchurl {
url = "https://github.com/microg/android_packages_apps_GmsCore/releases/download/v${version}/GmsCore-v${version}.apk";
sha256 = "0266zbmf20z7sa4xbgkq6f3qglrf8kcl24p6d87bzygm72340wxa";
};
});
packageName = "com.google.android.gms";
privileged = true;
privappPermissions = [ "FAKE_PACKAGE_SIGNATURE" "INSTALL_LOCATION_PROVIDER" "CHANGE_DEVICE_IDLE_TEMP_WHITELIST" "UPDATE_APP_OPS_STATS" ];
defaultPermissions = [ "FAKE_PACKAGE_SIGNATURE" ];
allowInPowerSave = true;
};

GsfProxy.apk = pkgs.fetchurl {
GsfProxy.apk = verifyApk (pkgs.fetchurl {
url = "https://github.com/microg/android_packages_apps_GsfProxy/releases/download/v0.1.0/GsfProxy.apk";
sha256 = "14ln6i1qg435x223x3vndd608mra19d58yqqhhf6mw018cbip2c6";
};
});

FakeStore = {
apk = pkgs.fetchurl {
apk = verifyApk (pkgs.fetchurl {
url = "https://github.com/microg/android_packages_apps_FakeStore/releases/download/v0.1.0/FakeStore-v0.1.0.apk";
sha256 = "1kp5v4qajp4cdx8pxw6j4776bcwc9f8jgfpiyllpk1kbhq92w1ci";
};
});
packageName = "com.android.vending";
privileged = true;
privappPermissions = [ "FAKE_PACKAGE_SIGNATURE" ];
Expand Down
42 changes: 42 additions & 0 deletions pkgs/build-tools/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{ lib, runCommand, androidPkgs, makeWrapper, jre8_headless }:

let
# getName snippet originally from nixpkgs/pkgs/build-support/trivial-builders.nix
getName = fname: apk:
if lib.elem (builtins.typeOf apk) [ "path" "string" ]
then lib.removeSuffix ".apk" (builtins.baseNameOf apk)
else
if builtins.isAttrs apk && builtins.hasAttr "name" apk
then lib.removeSuffix ".apk" apk.name
else throw "${fname}: please supply a `name` argument because a default name can only be computed when the `apk` is a path or is an attribute set with a `name` attribute.";

build-tools =
(androidPkgs.sdk (p: with p.stable; [ tools build-tools-30-0-2 ]))
+ "/share/android-sdk/build-tools/30.0.2";

apksigner = runCommand "apksigner" { nativeBuildInputs = [ makeWrapper ]; } ''
mkdir -p $out/bin
makeWrapper "${jre8_headless}/bin/java" "$out/bin/apksigner" \
--add-flags "-jar ${build-tools}/lib/apksigner.jar"
'';

signApk = { apk, keyPath, name ? (getName "signApk" apk) + "-signed.apk" }: runCommand name {} ''
cp ${apk} $out
${apksigner}/bin/apksigner sign --key ${keyPath}.pk8 --cert ${keyPath}.x509.pem $out
'';

# Currently only supports 1 signer.
verifyApk = { apk, sha256, name ? (getName "verifyApk" apk) + ".apk" }: runCommand name {} ''
sha256=$(${apksigner}/bin/apksigner verify --print-certs ${apk} | grep "^Signer #1 certificate SHA-256 digest: " | cut -d" " -f6 || exit 1)

if [[ "$sha256" = "${sha256}" ]]; then
echo "${name} APK certificate digest matches ${sha256}"
ln -s ${apk} $out
else
echo "${name} APK certificate digest $sha256 is not ${sha256}"
exit 1
fi
'';
in {
inherit build-tools apksigner signApk verifyApk;
}
8 changes: 8 additions & 0 deletions pkgs/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ let
fetchgerritpatchset = super.callPackage ./fetchgerritpatchset {};

nix-prefetch-git = super.callPackage ./nix-prefetch-git {};

###

inherit (super.callPackage ./build-tools {})
build-tools
apksigner
signApk
verifyApk;
};
in
import nixpkgs (args // {
Expand Down