Merge "APEX can be signed with different keys"
This commit is contained in:
@@ -348,6 +348,7 @@ bootstrap_go_package {
|
||||
],
|
||||
srcs: [
|
||||
"apex/apex.go",
|
||||
"apex/key.go",
|
||||
],
|
||||
pluginFor: ["soong_build"],
|
||||
}
|
||||
|
58
apex/apex.go
58
apex/apex.go
@@ -75,6 +75,7 @@ var (
|
||||
executableTag = dependencyTag{name: "executable"}
|
||||
javaLibTag = dependencyTag{name: "javaLib"}
|
||||
prebuiltTag = dependencyTag{name: "prebuilt"}
|
||||
keyTag = dependencyTag{name: "key"}
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -172,6 +173,9 @@ type apexBundleProperties struct {
|
||||
|
||||
// List of prebuilt files that are embedded inside this APEX bundle
|
||||
Prebuilts []string
|
||||
|
||||
// Name of the apex_key module that provides the private key to sign APEX
|
||||
Key *string
|
||||
}
|
||||
|
||||
type apexBundle struct {
|
||||
@@ -185,14 +189,6 @@ type apexBundle struct {
|
||||
}
|
||||
|
||||
func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
|
||||
// Native shared libs are added for all architectures of the device
|
||||
// i.e., native_shared_lib_modules: ["libc"] adds both 64 and 32 variation
|
||||
// of the module
|
||||
arches := ctx.DeviceConfig().Arches()
|
||||
if len(arches) == 0 {
|
||||
panic("device build with no primary arch")
|
||||
}
|
||||
|
||||
for _, arch := range ctx.MultiTargets() {
|
||||
// Use *FarVariation* to be able to depend on modules having
|
||||
// conflicting variations with this module. This is required since
|
||||
@@ -208,16 +204,21 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
|
||||
{Mutator: "arch", Variation: arch.String()},
|
||||
{Mutator: "image", Variation: "core"},
|
||||
}, executableTag, a.properties.Binaries...)
|
||||
|
||||
ctx.AddFarVariationDependencies([]blueprint.Variation{
|
||||
{Mutator: "arch", Variation: "android_common"},
|
||||
}, javaLibTag, a.properties.Java_libs...)
|
||||
|
||||
ctx.AddFarVariationDependencies([]blueprint.Variation{
|
||||
{Mutator: "arch", Variation: "android_common"},
|
||||
}, prebuiltTag, a.properties.Prebuilts...)
|
||||
}
|
||||
|
||||
ctx.AddFarVariationDependencies([]blueprint.Variation{
|
||||
{Mutator: "arch", Variation: "android_common"},
|
||||
}, javaLibTag, a.properties.Java_libs...)
|
||||
|
||||
ctx.AddFarVariationDependencies([]blueprint.Variation{
|
||||
{Mutator: "arch", Variation: "android_common"},
|
||||
}, prebuiltTag, a.properties.Prebuilts...)
|
||||
|
||||
if String(a.properties.Key) == "" {
|
||||
ctx.ModuleErrorf("key is missing")
|
||||
return
|
||||
}
|
||||
ctx.AddDependency(ctx.Module(), keyTag, String(a.properties.Key))
|
||||
}
|
||||
|
||||
func getCopyManifestForNativeLibrary(cc *cc.Module) (fileToCopy android.Path, dirInApex string) {
|
||||
@@ -259,34 +260,52 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
// files to copy -> dir in apex
|
||||
copyManifest := make(map[android.Path]string)
|
||||
|
||||
var keyFile android.Path
|
||||
|
||||
ctx.WalkDeps(func(child, parent android.Module) bool {
|
||||
if _, ok := parent.(*apexBundle); ok {
|
||||
// direct dependencies
|
||||
depTag := ctx.OtherModuleDependencyTag(child)
|
||||
depName := ctx.OtherModuleName(child)
|
||||
switch depTag {
|
||||
case sharedLibTag:
|
||||
if cc, ok := child.(*cc.Module); ok {
|
||||
fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc)
|
||||
copyManifest[fileToCopy] = dirInApex
|
||||
return true
|
||||
} else {
|
||||
ctx.PropertyErrorf("native_shared_libs", "%q is not a cc_library or cc_library_shared module", depName)
|
||||
}
|
||||
case executableTag:
|
||||
if cc, ok := child.(*cc.Module); ok {
|
||||
fileToCopy, dirInApex := getCopyManifestForExecutable(cc)
|
||||
copyManifest[fileToCopy] = dirInApex
|
||||
return true
|
||||
} else {
|
||||
ctx.PropertyErrorf("binaries", "%q is not a cc_binary module", depName)
|
||||
}
|
||||
case javaLibTag:
|
||||
if java, ok := child.(*java.Library); ok {
|
||||
fileToCopy, dirInApex := getCopyManifestForJavaLibrary(java)
|
||||
copyManifest[fileToCopy] = dirInApex
|
||||
return true
|
||||
} else {
|
||||
ctx.PropertyErrorf("java_libs", "%q is not a java_library module", depName)
|
||||
}
|
||||
case prebuiltTag:
|
||||
if prebuilt, ok := child.(*android.PrebuiltEtc); ok {
|
||||
fileToCopy, dirInApex := getCopyManifestForPrebuiltEtc(prebuilt)
|
||||
copyManifest[fileToCopy] = dirInApex
|
||||
return true
|
||||
} else {
|
||||
ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
|
||||
}
|
||||
case keyTag:
|
||||
if key, ok := child.(*apexKey); ok {
|
||||
keyFile = key.private_key_file
|
||||
return false
|
||||
} else {
|
||||
ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -330,8 +349,6 @@ 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"))
|
||||
// TODO(b/114488804) make this customizable
|
||||
key := android.PathForSource(ctx, "system/apex/apexer/testdata/testkey.pem")
|
||||
|
||||
a.outputFile = android.PathForModuleOut(ctx, a.ModuleBase.Name()+apexSuffix)
|
||||
|
||||
@@ -351,7 +368,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
copyCommands = append(copyCommands, "cp "+src.String()+" "+dest_path)
|
||||
}
|
||||
implicitInputs := append(android.Paths(nil), filesToCopy...)
|
||||
implicitInputs = append(implicitInputs, cannedFsConfig, manifest, fileContexts, key)
|
||||
implicitInputs = append(implicitInputs, cannedFsConfig, manifest, fileContexts, keyFile)
|
||||
outHostBinDir := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "bin").String()
|
||||
prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
|
||||
ctx.ModuleBuild(pctx, android.ModuleBuildParams{
|
||||
@@ -365,7 +382,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
"manifest": manifest.String(),
|
||||
"file_contexts": fileContexts.String(),
|
||||
"canned_fs_config": cannedFsConfig.String(),
|
||||
"key": key.String(),
|
||||
"key": keyFile.String(),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -382,6 +399,7 @@ func (a *apexBundle) AndroidMk() android.AndroidMkData {
|
||||
fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", a.outputFile.String())
|
||||
fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", filepath.Join("$(OUT_DIR)", a.installDir.RelPathString()))
|
||||
fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", name+apexSuffix)
|
||||
fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES :=", String(a.properties.Key))
|
||||
fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
|
||||
}}
|
||||
}
|
||||
|
88
apex/key.go
Normal file
88
apex/key.go
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright (C) 2018 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package apex
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"android/soong/android"
|
||||
"github.com/google/blueprint/proptools"
|
||||
)
|
||||
|
||||
var String = proptools.String
|
||||
|
||||
func init() {
|
||||
android.RegisterModuleType("apex_key", apexKeyFactory)
|
||||
}
|
||||
|
||||
type apexKey struct {
|
||||
android.ModuleBase
|
||||
|
||||
properties apexKeyProperties
|
||||
|
||||
public_key_file android.Path
|
||||
private_key_file android.Path
|
||||
|
||||
keyName string
|
||||
}
|
||||
|
||||
type apexKeyProperties struct {
|
||||
// Path to the public key file in avbpubkey format. Installed to the device.
|
||||
// Base name of the file is used as the ID for the key.
|
||||
Public_key *string
|
||||
// Path to the private key file in pem format. Used to sign APEXs.
|
||||
Private_key *string
|
||||
}
|
||||
|
||||
func apexKeyFactory() android.Module {
|
||||
module := &apexKey{}
|
||||
module.AddProperties(&module.properties)
|
||||
android.InitAndroidModule(module)
|
||||
return module
|
||||
}
|
||||
|
||||
func (m *apexKey) DepsMutator(ctx android.BottomUpMutatorContext) {
|
||||
}
|
||||
|
||||
func (m *apexKey) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
m.public_key_file = android.PathForModuleSrc(ctx, String(m.properties.Public_key))
|
||||
m.private_key_file = android.PathForModuleSrc(ctx, String(m.properties.Private_key))
|
||||
|
||||
pubKeyName := m.public_key_file.Base()[0 : len(m.public_key_file.Base())-len(m.public_key_file.Ext())]
|
||||
privKeyName := m.private_key_file.Base()[0 : len(m.private_key_file.Base())-len(m.private_key_file.Ext())]
|
||||
|
||||
if pubKeyName != privKeyName {
|
||||
ctx.ModuleErrorf("public_key %q (keyname:%q) and private_key %q (keyname:%q) do not have same keyname",
|
||||
m.public_key_file.String(), pubKeyName, m.private_key_file, privKeyName)
|
||||
return
|
||||
}
|
||||
m.keyName = pubKeyName
|
||||
|
||||
ctx.InstallFile(android.PathForModuleInstall(ctx, "etc/security/apex"), m.keyName, m.public_key_file)
|
||||
}
|
||||
|
||||
func (m *apexKey) AndroidMk() android.AndroidMkData {
|
||||
return android.AndroidMkData{
|
||||
Class: "ETC",
|
||||
OutputFile: android.OptionalPathForPath(m.public_key_file),
|
||||
Extra: []android.AndroidMkExtraFunc{
|
||||
func(w io.Writer, outputFile android.Path) {
|
||||
fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", "$(TARGET_OUT)/etc/security/apex")
|
||||
fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", m.keyName)
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user