Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c00cbd9e authored by Jiyong Park's avatar Jiyong Park
Browse files

APEXs are signed with apk signer

The entire APEX (which is a zip file) is signed with the apk signer.
Certificate can be specified via the 'certificate' property just like
ordinary apps. Note: multiple additional certificates are not supported.

Bug: 115721587
Test: m apex.test
Test: jarsigner -verify -verbose -certs .../apex.test.apex shows the
certificate info

Change-Id: Ia4c898d3427779a3809fdc683b85d7661ca65137
parent a758cda4
Loading
Loading
Loading
Loading
+49 −7
Original line number Diff line number Diff line
@@ -76,10 +76,12 @@ var (
	javaLibTag     = dependencyTag{name: "javaLib"}
	prebuiltTag    = dependencyTag{name: "prebuilt"}
	keyTag         = dependencyTag{name: "key"}
	certificateTag = dependencyTag{name: "certificate"}
)

func init() {
	pctx.Import("android/soong/common")
	pctx.Import("android/soong/java")
	pctx.HostBinToolVariable("apexer", "apexer")
	// ART minimal builds (using the master-art manifest) do not have the "frameworks/base"
	// projects, and hence cannot built 'aapt2'. Use the SDK prebuilt instead.
@@ -188,6 +190,10 @@ type apexBundleProperties struct {
	// Name of the apex_key module that provides the private key to sign APEX
	Key *string

	// The name of a certificate in the default certificate directory, blank to use the default product certificate,
	// or an android_app_certificate module name in the form ":module".
	Certificate *string

	Multilib struct {
		First struct {
			// List of native libraries whose compile_multilib is "first"
@@ -324,6 +330,11 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
		return
	}
	ctx.AddDependency(ctx.Module(), keyTag, String(a.properties.Key))

	cert := android.SrcIsModule(String(a.properties.Certificate))
	if cert != "" {
		ctx.AddDependency(ctx.Module(), certificateTag, cert)
	}
}

func getCopyManifestForNativeLibrary(cc *cc.Module) (fileToCopy android.Path, dirInApex string) {
@@ -366,6 +377,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	copyManifest := make(map[android.Path]string)

	var keyFile android.Path
	var certificate java.Certificate

	ctx.WalkDeps(func(child, parent android.Module) bool {
		if _, ok := parent.(*apexBundle); ok {
@@ -412,6 +424,13 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
				} else {
					ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
				}
			case certificateTag:
				if dep, ok := child.(*java.AndroidAppCertificate); ok {
					certificate = dep.Certificate
					return false
				} else {
					ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName)
				}
			}
		} else {
			// indirect dependencies
@@ -426,6 +445,18 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
		return false
	})

	cert := String(a.properties.Certificate)
	if cert != "" && android.SrcIsModule(cert) == "" {
		defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
		certificate = java.Certificate{
			defaultDir.Join(ctx, cert+".x509.pem"),
			defaultDir.Join(ctx, cert+".pk8"),
		}
	} else if cert == "" {
		pem, key := ctx.Config().DefaultAppCertificate(ctx)
		certificate = java.Certificate{pem, key}
	}

	// files and dirs that will be created in apex
	var readOnlyPaths []string
	var executablePaths []string // this also includes dirs
@@ -455,7 +486,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	manifest := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "manifest.json"))
	fileContexts := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.File_contexts, "file_contexts"))

	a.outputFile = android.PathForModuleOut(ctx, a.ModuleBase.Name()+apexSuffix)
	unsignedOutputFile := android.PathForModuleOut(ctx, a.ModuleBase.Name()+apexSuffix+".unsigned")

	filesToCopy := []android.Path{}
	for file := range copyManifest {
@@ -479,7 +510,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
		Rule:      apexRule,
		Implicits: implicitInputs,
		Output:    a.outputFile,
		Output:    unsignedOutputFile,
		Args: map[string]string{
			"tool_path":        outHostBinDir + ":" + prebuiltSdkToolsBinDir,
			"image_dir":        android.PathForModuleOut(ctx, "image").String(),
@@ -491,6 +522,17 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
		},
	})

	a.outputFile = android.PathForModuleOut(ctx, a.ModuleBase.Name()+apexSuffix)
	ctx.Build(pctx, android.BuildParams{
		Rule:        java.Signapk,
		Description: "signapk",
		Output:      a.outputFile,
		Input:       unsignedOutputFile,
		Args: map[string]string{
			"certificates": strings.Join([]string{certificate.Pem.String(), certificate.Key.String()}, " "),
		},
	})

	a.installDir = android.PathForModuleInstall(ctx, "apex")
}

+1 −1
Original line number Diff line number Diff line
@@ -239,7 +239,7 @@ func (app *AndroidApp) AndroidMk() android.AndroidMkData {
					fmt.Fprintln(w, "LOCAL_PRIVILEGED_MODULE := true")
				}

				fmt.Fprintln(w, "LOCAL_CERTIFICATE :=", app.certificate.pem.String())
				fmt.Fprintln(w, "LOCAL_CERTIFICATE :=", app.certificate.Pem.String())
				if len(app.appProperties.Overrides) > 0 {
					fmt.Fprintln(w, "LOCAL_OVERRIDES_PACKAGES := "+strings.Join(app.appProperties.Overrides, " "))
				}
+12 −12
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ type AndroidApp struct {
	Library
	aapt

	certificate certificate
	certificate Certificate

	appProperties appProperties

@@ -99,8 +99,8 @@ func (a *AndroidApp) ExportedManifest() android.Path {

var _ AndroidLibraryDependency = (*AndroidApp)(nil)

type certificate struct {
	pem, key android.Path
type Certificate struct {
	Pem, Key android.Path
}

func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -237,7 +237,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
		dexJarFile = nil
	}

	var certificates []certificate
	var certificates []Certificate

	var jniJarFile android.WritablePath
	jniLibs, certificateDeps := a.collectAppDeps(ctx)
@@ -262,16 +262,16 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
		certificateDeps = certificateDeps[1:]
	} else if cert != "" {
		defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
		a.certificate = certificate{
		a.certificate = Certificate{
			defaultDir.Join(ctx, cert+".x509.pem"),
			defaultDir.Join(ctx, cert+".pk8"),
		}
	} else {
		pem, key := ctx.Config().DefaultAppCertificate(ctx)
		a.certificate = certificate{pem, key}
		a.certificate = Certificate{pem, key}
	}

	certificates = append([]certificate{a.certificate}, certificateDeps...)
	certificates = append([]Certificate{a.certificate}, certificateDeps...)

	packageFile := android.PathForModuleOut(ctx, "package.apk")
	CreateAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates)
@@ -287,9 +287,9 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
	}
}

func (a *AndroidApp) collectAppDeps(ctx android.ModuleContext) ([]jniLib, []certificate) {
func (a *AndroidApp) collectAppDeps(ctx android.ModuleContext) ([]jniLib, []Certificate) {
	var jniLibs []jniLib
	var certificates []certificate
	var certificates []Certificate

	ctx.VisitDirectDeps(func(module android.Module) {
		otherName := ctx.OtherModuleName(module)
@@ -313,7 +313,7 @@ func (a *AndroidApp) collectAppDeps(ctx android.ModuleContext) ([]jniLib, []cert
			}
		} else if tag == certificateTag {
			if dep, ok := module.(*AndroidAppCertificate); ok {
				certificates = append(certificates, dep.certificate)
				certificates = append(certificates, dep.Certificate)
			} else {
				ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
			}
@@ -446,7 +446,7 @@ func AndroidTestHelperAppFactory() android.Module {
type AndroidAppCertificate struct {
	android.ModuleBase
	properties  AndroidAppCertificateProperties
	certificate certificate
	Certificate Certificate
}

type AndroidAppCertificateProperties struct {
@@ -466,7 +466,7 @@ func (c *AndroidAppCertificate) DepsMutator(ctx android.BottomUpMutatorContext)

func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	cert := String(c.properties.Certificate)
	c.certificate = certificate{
	c.Certificate = Certificate{
		android.PathForModuleSrc(ctx, cert+".x509.pem"),
		android.PathForModuleSrc(ctx, cert+".pk8"),
	}
+4 −4
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ import (
)

var (
	signapk = pctx.AndroidStaticRule("signapk",
	Signapk = pctx.AndroidStaticRule("signapk",
		blueprint.RuleParams{
			Command: `${config.JavaCmd} -Djava.library.path=$$(dirname $signapkJniLibrary) ` +
				`-jar $signapkCmd $certificates $in $out`,
@@ -63,7 +63,7 @@ var combineApk = pctx.AndroidStaticRule("combineApk",
	})

func CreateAppPackage(ctx android.ModuleContext, outputFile android.WritablePath,
	resJarFile, jniJarFile, dexJarFile android.Path, certificates []certificate) {
	resJarFile, jniJarFile, dexJarFile android.Path, certificates []Certificate) {

	unsignedApk := android.PathForModuleOut(ctx, "unsigned.apk")

@@ -84,11 +84,11 @@ func CreateAppPackage(ctx android.ModuleContext, outputFile android.WritablePath

	var certificateArgs []string
	for _, c := range certificates {
		certificateArgs = append(certificateArgs, c.pem.String(), c.key.String())
		certificateArgs = append(certificateArgs, c.Pem.String(), c.Key.String())
	}

	ctx.Build(pctx, android.BuildParams{
		Rule:        signapk,
		Rule:        Signapk,
		Description: "signapk",
		Output:      outputFile,
		Input:       unsignedApk,