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
This commit is contained in:
56
apex/apex.go
56
apex/apex.go
@@ -71,15 +71,17 @@ type dependencyTag struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
sharedLibTag = dependencyTag{name: "sharedLib"}
|
sharedLibTag = dependencyTag{name: "sharedLib"}
|
||||||
executableTag = dependencyTag{name: "executable"}
|
executableTag = dependencyTag{name: "executable"}
|
||||||
javaLibTag = dependencyTag{name: "javaLib"}
|
javaLibTag = dependencyTag{name: "javaLib"}
|
||||||
prebuiltTag = dependencyTag{name: "prebuilt"}
|
prebuiltTag = dependencyTag{name: "prebuilt"}
|
||||||
keyTag = dependencyTag{name: "key"}
|
keyTag = dependencyTag{name: "key"}
|
||||||
|
certificateTag = dependencyTag{name: "certificate"}
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
pctx.Import("android/soong/common")
|
pctx.Import("android/soong/common")
|
||||||
|
pctx.Import("android/soong/java")
|
||||||
pctx.HostBinToolVariable("apexer", "apexer")
|
pctx.HostBinToolVariable("apexer", "apexer")
|
||||||
// ART minimal builds (using the master-art manifest) do not have the "frameworks/base"
|
// 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.
|
// 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
|
// Name of the apex_key module that provides the private key to sign APEX
|
||||||
Key *string
|
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 {
|
Multilib struct {
|
||||||
First struct {
|
First struct {
|
||||||
// List of native libraries whose compile_multilib is "first"
|
// List of native libraries whose compile_multilib is "first"
|
||||||
@@ -324,6 +330,11 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.AddDependency(ctx.Module(), keyTag, String(a.properties.Key))
|
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) {
|
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)
|
copyManifest := make(map[android.Path]string)
|
||||||
|
|
||||||
var keyFile android.Path
|
var keyFile android.Path
|
||||||
|
var certificate java.Certificate
|
||||||
|
|
||||||
ctx.WalkDeps(func(child, parent android.Module) bool {
|
ctx.WalkDeps(func(child, parent android.Module) bool {
|
||||||
if _, ok := parent.(*apexBundle); ok {
|
if _, ok := parent.(*apexBundle); ok {
|
||||||
@@ -412,6 +424,13 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
} else {
|
} else {
|
||||||
ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
|
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 {
|
} else {
|
||||||
// indirect dependencies
|
// indirect dependencies
|
||||||
@@ -426,6 +445,18 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
return false
|
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
|
// files and dirs that will be created in apex
|
||||||
var readOnlyPaths []string
|
var readOnlyPaths []string
|
||||||
var executablePaths []string // this also includes dirs
|
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"))
|
manifest := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "manifest.json"))
|
||||||
fileContexts := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.File_contexts, "file_contexts"))
|
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{}
|
filesToCopy := []android.Path{}
|
||||||
for file := range copyManifest {
|
for file := range copyManifest {
|
||||||
@@ -479,7 +510,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
ctx.ModuleBuild(pctx, android.ModuleBuildParams{
|
ctx.ModuleBuild(pctx, android.ModuleBuildParams{
|
||||||
Rule: apexRule,
|
Rule: apexRule,
|
||||||
Implicits: implicitInputs,
|
Implicits: implicitInputs,
|
||||||
Output: a.outputFile,
|
Output: unsignedOutputFile,
|
||||||
Args: map[string]string{
|
Args: map[string]string{
|
||||||
"tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
|
"tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
|
||||||
"image_dir": android.PathForModuleOut(ctx, "image").String(),
|
"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")
|
a.installDir = android.PathForModuleInstall(ctx, "apex")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -239,7 +239,7 @@ func (app *AndroidApp) AndroidMk() android.AndroidMkData {
|
|||||||
fmt.Fprintln(w, "LOCAL_PRIVILEGED_MODULE := true")
|
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 {
|
if len(app.appProperties.Overrides) > 0 {
|
||||||
fmt.Fprintln(w, "LOCAL_OVERRIDES_PACKAGES := "+strings.Join(app.appProperties.Overrides, " "))
|
fmt.Fprintln(w, "LOCAL_OVERRIDES_PACKAGES := "+strings.Join(app.appProperties.Overrides, " "))
|
||||||
}
|
}
|
||||||
|
24
java/app.go
24
java/app.go
@@ -76,7 +76,7 @@ type AndroidApp struct {
|
|||||||
Library
|
Library
|
||||||
aapt
|
aapt
|
||||||
|
|
||||||
certificate certificate
|
certificate Certificate
|
||||||
|
|
||||||
appProperties appProperties
|
appProperties appProperties
|
||||||
|
|
||||||
@@ -99,8 +99,8 @@ func (a *AndroidApp) ExportedManifest() android.Path {
|
|||||||
|
|
||||||
var _ AndroidLibraryDependency = (*AndroidApp)(nil)
|
var _ AndroidLibraryDependency = (*AndroidApp)(nil)
|
||||||
|
|
||||||
type certificate struct {
|
type Certificate struct {
|
||||||
pem, key android.Path
|
Pem, Key android.Path
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
|
func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
|
||||||
@@ -237,7 +237,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
dexJarFile = nil
|
dexJarFile = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var certificates []certificate
|
var certificates []Certificate
|
||||||
|
|
||||||
var jniJarFile android.WritablePath
|
var jniJarFile android.WritablePath
|
||||||
jniLibs, certificateDeps := a.collectAppDeps(ctx)
|
jniLibs, certificateDeps := a.collectAppDeps(ctx)
|
||||||
@@ -262,16 +262,16 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
certificateDeps = certificateDeps[1:]
|
certificateDeps = certificateDeps[1:]
|
||||||
} else if cert != "" {
|
} else if cert != "" {
|
||||||
defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
|
defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
|
||||||
a.certificate = certificate{
|
a.certificate = Certificate{
|
||||||
defaultDir.Join(ctx, cert+".x509.pem"),
|
defaultDir.Join(ctx, cert+".x509.pem"),
|
||||||
defaultDir.Join(ctx, cert+".pk8"),
|
defaultDir.Join(ctx, cert+".pk8"),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pem, key := ctx.Config().DefaultAppCertificate(ctx)
|
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")
|
packageFile := android.PathForModuleOut(ctx, "package.apk")
|
||||||
CreateAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates)
|
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 jniLibs []jniLib
|
||||||
var certificates []certificate
|
var certificates []Certificate
|
||||||
|
|
||||||
ctx.VisitDirectDeps(func(module android.Module) {
|
ctx.VisitDirectDeps(func(module android.Module) {
|
||||||
otherName := ctx.OtherModuleName(module)
|
otherName := ctx.OtherModuleName(module)
|
||||||
@@ -313,7 +313,7 @@ func (a *AndroidApp) collectAppDeps(ctx android.ModuleContext) ([]jniLib, []cert
|
|||||||
}
|
}
|
||||||
} else if tag == certificateTag {
|
} else if tag == certificateTag {
|
||||||
if dep, ok := module.(*AndroidAppCertificate); ok {
|
if dep, ok := module.(*AndroidAppCertificate); ok {
|
||||||
certificates = append(certificates, dep.certificate)
|
certificates = append(certificates, dep.Certificate)
|
||||||
} else {
|
} else {
|
||||||
ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
|
ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
|
||||||
}
|
}
|
||||||
@@ -446,7 +446,7 @@ func AndroidTestHelperAppFactory() android.Module {
|
|||||||
type AndroidAppCertificate struct {
|
type AndroidAppCertificate struct {
|
||||||
android.ModuleBase
|
android.ModuleBase
|
||||||
properties AndroidAppCertificateProperties
|
properties AndroidAppCertificateProperties
|
||||||
certificate certificate
|
Certificate Certificate
|
||||||
}
|
}
|
||||||
|
|
||||||
type AndroidAppCertificateProperties struct {
|
type AndroidAppCertificateProperties struct {
|
||||||
@@ -466,7 +466,7 @@ func (c *AndroidAppCertificate) DepsMutator(ctx android.BottomUpMutatorContext)
|
|||||||
|
|
||||||
func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
cert := String(c.properties.Certificate)
|
cert := String(c.properties.Certificate)
|
||||||
c.certificate = certificate{
|
c.Certificate = Certificate{
|
||||||
android.PathForModuleSrc(ctx, cert+".x509.pem"),
|
android.PathForModuleSrc(ctx, cert+".x509.pem"),
|
||||||
android.PathForModuleSrc(ctx, cert+".pk8"),
|
android.PathForModuleSrc(ctx, cert+".pk8"),
|
||||||
}
|
}
|
||||||
|
@@ -29,7 +29,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
signapk = pctx.AndroidStaticRule("signapk",
|
Signapk = pctx.AndroidStaticRule("signapk",
|
||||||
blueprint.RuleParams{
|
blueprint.RuleParams{
|
||||||
Command: `${config.JavaCmd} -Djava.library.path=$$(dirname $signapkJniLibrary) ` +
|
Command: `${config.JavaCmd} -Djava.library.path=$$(dirname $signapkJniLibrary) ` +
|
||||||
`-jar $signapkCmd $certificates $in $out`,
|
`-jar $signapkCmd $certificates $in $out`,
|
||||||
@@ -63,7 +63,7 @@ var combineApk = pctx.AndroidStaticRule("combineApk",
|
|||||||
})
|
})
|
||||||
|
|
||||||
func CreateAppPackage(ctx android.ModuleContext, outputFile android.WritablePath,
|
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")
|
unsignedApk := android.PathForModuleOut(ctx, "unsigned.apk")
|
||||||
|
|
||||||
@@ -84,11 +84,11 @@ func CreateAppPackage(ctx android.ModuleContext, outputFile android.WritablePath
|
|||||||
|
|
||||||
var certificateArgs []string
|
var certificateArgs []string
|
||||||
for _, c := range certificates {
|
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{
|
ctx.Build(pctx, android.BuildParams{
|
||||||
Rule: signapk,
|
Rule: Signapk,
|
||||||
Description: "signapk",
|
Description: "signapk",
|
||||||
Output: outputFile,
|
Output: outputFile,
|
||||||
Input: unsignedApk,
|
Input: unsignedApk,
|
||||||
|
Reference in New Issue
Block a user