123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- // 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"
- "sort"
- "strings"
- "android/soong/android"
- "android/soong/bazel"
- "github.com/google/blueprint/proptools"
- )
- var String = proptools.String
- func init() {
- registerApexKeyBuildComponents(android.InitRegistrationContext)
- }
- func registerApexKeyBuildComponents(ctx android.RegistrationContext) {
- ctx.RegisterModuleType("apex_key", ApexKeyFactory)
- ctx.RegisterParallelSingletonType("apex_keys_text", apexKeysTextFactory)
- }
- type apexKey struct {
- android.ModuleBase
- android.BazelModuleBase
- properties apexKeyProperties
- publicKeyFile android.Path
- privateKeyFile android.Path
- }
- type apexKeyProperties struct {
- // Path or module 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 `android:"path"`
- // Path or module to the private key file in pem format. Used to sign APEXs.
- Private_key *string `android:"path"`
- // Whether this key is installable to one of the partitions. Defualt: true.
- Installable *bool
- }
- func ApexKeyFactory() android.Module {
- module := &apexKey{}
- module.AddProperties(&module.properties)
- android.InitAndroidArchModule(module, android.HostAndDeviceDefault, android.MultilibCommon)
- android.InitBazelModule(module)
- return module
- }
- func (m *apexKey) installable() bool {
- return false
- }
- func (m *apexKey) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- // If the keys are from other modules (i.e. :module syntax) respect it.
- // Otherwise, try to locate the key files in the default cert dir or
- // in the local module dir
- if android.SrcIsModule(String(m.properties.Public_key)) != "" {
- m.publicKeyFile = android.PathForModuleSrc(ctx, String(m.properties.Public_key))
- } else {
- m.publicKeyFile = ctx.Config().ApexKeyDir(ctx).Join(ctx, String(m.properties.Public_key))
- // If not found, fall back to the local key pairs
- if !android.ExistentPathForSource(ctx, m.publicKeyFile.String()).Valid() {
- m.publicKeyFile = android.PathForModuleSrc(ctx, String(m.properties.Public_key))
- }
- }
- if android.SrcIsModule(String(m.properties.Private_key)) != "" {
- m.privateKeyFile = android.PathForModuleSrc(ctx, String(m.properties.Private_key))
- } else {
- m.privateKeyFile = ctx.Config().ApexKeyDir(ctx).Join(ctx, String(m.properties.Private_key))
- if !android.ExistentPathForSource(ctx, m.privateKeyFile.String()).Valid() {
- m.privateKeyFile = android.PathForModuleSrc(ctx, String(m.properties.Private_key))
- }
- }
- pubKeyName := m.publicKeyFile.Base()[0 : len(m.publicKeyFile.Base())-len(m.publicKeyFile.Ext())]
- privKeyName := m.privateKeyFile.Base()[0 : len(m.privateKeyFile.Base())-len(m.privateKeyFile.Ext())]
- if m.properties.Public_key != nil && m.properties.Private_key != nil && pubKeyName != privKeyName {
- ctx.ModuleErrorf("public_key %q (keyname:%q) and private_key %q (keyname:%q) do not have same keyname",
- m.publicKeyFile.String(), pubKeyName, m.privateKeyFile, privKeyName)
- return
- }
- }
- // //////////////////////////////////////////////////////////////////////
- // apex_keys_text
- type apexKeysText struct {
- output android.OutputPath
- }
- func (s *apexKeysText) GenerateBuildActions(ctx android.SingletonContext) {
- s.output = android.PathForOutput(ctx, "apexkeys.txt")
- type apexKeyEntry struct {
- name string
- presigned bool
- publicKey string
- privateKey string
- containerCertificate string
- containerPrivateKey string
- partition string
- signTool string
- }
- toString := func(e apexKeyEntry) string {
- signTool := ""
- if e.signTool != "" {
- signTool = fmt.Sprintf(" sign_tool=%q", e.signTool)
- }
- format := "name=%q public_key=%q private_key=%q container_certificate=%q container_private_key=%q partition=%q%s\n"
- if e.presigned {
- return fmt.Sprintf(format, e.name, "PRESIGNED", "PRESIGNED", "PRESIGNED", "PRESIGNED", e.partition, signTool)
- } else {
- return fmt.Sprintf(format, e.name, e.publicKey, e.privateKey, e.containerCertificate, e.containerPrivateKey, e.partition, signTool)
- }
- }
- apexKeyMap := make(map[string]apexKeyEntry)
- ctx.VisitAllModules(func(module android.Module) {
- if m, ok := module.(*apexBundle); ok && m.Enabled() && m.installable() {
- pem, key := m.getCertificateAndPrivateKey(ctx)
- apexKeyMap[m.Name()] = apexKeyEntry{
- name: m.Name() + ".apex",
- presigned: false,
- publicKey: m.publicKeyFile.String(),
- privateKey: m.privateKeyFile.String(),
- containerCertificate: pem.String(),
- containerPrivateKey: key.String(),
- partition: m.PartitionTag(ctx.DeviceConfig()),
- signTool: proptools.String(m.properties.Custom_sign_tool),
- }
- }
- })
- // Find prebuilts and let them override apexBundle if they are preferred
- ctx.VisitAllModules(func(module android.Module) {
- if m, ok := module.(*Prebuilt); ok && m.Enabled() && m.installable() &&
- m.Prebuilt().UsePrebuilt() {
- apexKeyMap[m.BaseModuleName()] = apexKeyEntry{
- name: m.InstallFilename(),
- presigned: true,
- partition: m.PartitionTag(ctx.DeviceConfig()),
- }
- }
- })
- // Find apex_set and let them override apexBundle or prebuilts. This is done in a separate pass
- // so that apex_set are not overridden by prebuilts.
- ctx.VisitAllModules(func(module android.Module) {
- if m, ok := module.(*ApexSet); ok && m.Enabled() {
- entry := apexKeyEntry{
- name: m.InstallFilename(),
- presigned: true,
- partition: m.PartitionTag(ctx.DeviceConfig()),
- }
- apexKeyMap[m.BaseModuleName()] = entry
- }
- })
- // iterating over map does not give consistent ordering in golang
- var moduleNames []string
- for key, _ := range apexKeyMap {
- moduleNames = append(moduleNames, key)
- }
- sort.Strings(moduleNames)
- var filecontent strings.Builder
- for _, name := range moduleNames {
- filecontent.WriteString(toString(apexKeyMap[name]))
- }
- android.WriteFileRule(ctx, s.output, filecontent.String())
- }
- func apexKeysTextFactory() android.Singleton {
- return &apexKeysText{}
- }
- func (s *apexKeysText) MakeVars(ctx android.MakeVarsContext) {
- ctx.Strict("SOONG_APEX_KEYS_FILE", s.output.String())
- }
- // For Bazel / bp2build
- type bazelApexKeyAttributes struct {
- Public_key bazel.LabelAttribute
- Public_key_name bazel.StringAttribute
- Private_key bazel.LabelAttribute
- Private_key_name bazel.StringAttribute
- }
- // ConvertWithBp2build performs conversion apexKey for bp2build
- func (m *apexKey) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
- apexKeyBp2BuildInternal(ctx, m)
- }
- func apexKeyBp2BuildInternal(ctx android.TopDownMutatorContext, module *apexKey) {
- privateKeyLabelAttribute, privateKeyNameAttribute :=
- android.BazelStringOrLabelFromProp(ctx, module.properties.Private_key)
- publicKeyLabelAttribute, publicKeyNameAttribute :=
- android.BazelStringOrLabelFromProp(ctx, module.properties.Public_key)
- attrs := &bazelApexKeyAttributes{
- Private_key: privateKeyLabelAttribute,
- Private_key_name: privateKeyNameAttribute,
- Public_key: publicKeyLabelAttribute,
- Public_key_name: publicKeyNameAttribute,
- }
- props := bazel.BazelTargetModuleProperties{
- Rule_class: "apex_key",
- Bzl_load_location: "//build/bazel/rules/apex:apex_key.bzl",
- }
- ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs)
- }
|