blob: 4bd0dc4f9a82f3a6bf893c4901f3ab0a193f6033 [file] [log] [blame]
Jiyong Parkff1458f2018-10-12 21:49:38 +09001// Copyright (C) 2018 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package apex
16
17import (
18 "fmt"
Jiyong Park4d277042019-04-23 18:00:10 +090019 "sort"
Jiyong Park0ca3ce82019-02-18 15:25:04 +090020 "strings"
Jiyong Parkff1458f2018-10-12 21:49:38 +090021
22 "android/soong/android"
Colin Cross5f692ec2019-02-01 16:53:07 -080023
Jiyong Parkff1458f2018-10-12 21:49:38 +090024 "github.com/google/blueprint/proptools"
25)
26
27var String = proptools.String
28
29func init() {
Paul Duffin667893c2021-03-09 22:34:13 +000030 registerApexKeyBuildComponents(android.InitRegistrationContext)
31}
32
33func registerApexKeyBuildComponents(ctx android.RegistrationContext) {
34 ctx.RegisterModuleType("apex_key", ApexKeyFactory)
35 ctx.RegisterSingletonType("apex_keys_text", apexKeysTextFactory)
Jiyong Parkff1458f2018-10-12 21:49:38 +090036}
37
38type apexKey struct {
39 android.ModuleBase
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -040040 android.BazelModuleBase
Jiyong Parkff1458f2018-10-12 21:49:38 +090041
42 properties apexKeyProperties
43
Jaewoong Jung18aefc12020-12-21 09:11:10 -080044 publicKeyFile android.Path
45 privateKeyFile android.Path
Jiyong Parkff1458f2018-10-12 21:49:38 +090046
47 keyName string
48}
49
50type apexKeyProperties struct {
Jiyong Park67882562019-03-21 01:11:21 +090051 // Path or module to the public key file in avbpubkey format. Installed to the device.
Jiyong Parkff1458f2018-10-12 21:49:38 +090052 // Base name of the file is used as the ID for the key.
Jiyong Park67882562019-03-21 01:11:21 +090053 Public_key *string `android:"path"`
54 // Path or module to the private key file in pem format. Used to sign APEXs.
55 Private_key *string `android:"path"`
Jiyong Park50d99202018-12-27 13:32:34 +090056
57 // Whether this key is installable to one of the partitions. Defualt: true.
58 Installable *bool
Jiyong Parkff1458f2018-10-12 21:49:38 +090059}
60
Jiyong Parkd1063c12019-07-17 20:08:41 +090061func ApexKeyFactory() android.Module {
Jiyong Parkff1458f2018-10-12 21:49:38 +090062 module := &apexKey{}
63 module.AddProperties(&module.properties)
dimitryf8071672019-04-11 17:27:11 +020064 android.InitAndroidArchModule(module, android.HostAndDeviceDefault, android.MultilibCommon)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -040065 android.InitBazelModule(module)
Jiyong Parkff1458f2018-10-12 21:49:38 +090066 return module
67}
68
Jiyong Park50d99202018-12-27 13:32:34 +090069func (m *apexKey) installable() bool {
Jiyong Park42cca6c2019-04-01 11:15:50 +090070 return false
Jiyong Park50d99202018-12-27 13:32:34 +090071}
72
Jiyong Parkff1458f2018-10-12 21:49:38 +090073func (m *apexKey) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jiyong Park67882562019-03-21 01:11:21 +090074 // If the keys are from other modules (i.e. :module syntax) respect it.
75 // Otherwise, try to locate the key files in the default cert dir or
76 // in the local module dir
77 if android.SrcIsModule(String(m.properties.Public_key)) != "" {
Jaewoong Jung18aefc12020-12-21 09:11:10 -080078 m.publicKeyFile = android.PathForModuleSrc(ctx, String(m.properties.Public_key))
Jiyong Park67882562019-03-21 01:11:21 +090079 } else {
Jaewoong Jung18aefc12020-12-21 09:11:10 -080080 m.publicKeyFile = ctx.Config().ApexKeyDir(ctx).Join(ctx, String(m.properties.Public_key))
Jiyong Park67882562019-03-21 01:11:21 +090081 // If not found, fall back to the local key pairs
Jaewoong Jung18aefc12020-12-21 09:11:10 -080082 if !android.ExistentPathForSource(ctx, m.publicKeyFile.String()).Valid() {
83 m.publicKeyFile = android.PathForModuleSrc(ctx, String(m.properties.Public_key))
Jiyong Park67882562019-03-21 01:11:21 +090084 }
Jiyong Park9335a262018-12-24 11:31:58 +090085 }
Jiyong Park67882562019-03-21 01:11:21 +090086
87 if android.SrcIsModule(String(m.properties.Private_key)) != "" {
Jaewoong Jung18aefc12020-12-21 09:11:10 -080088 m.privateKeyFile = android.PathForModuleSrc(ctx, String(m.properties.Private_key))
Jiyong Park67882562019-03-21 01:11:21 +090089 } else {
Jaewoong Jung18aefc12020-12-21 09:11:10 -080090 m.privateKeyFile = ctx.Config().ApexKeyDir(ctx).Join(ctx, String(m.properties.Private_key))
91 if !android.ExistentPathForSource(ctx, m.privateKeyFile.String()).Valid() {
92 m.privateKeyFile = android.PathForModuleSrc(ctx, String(m.properties.Private_key))
Jiyong Park67882562019-03-21 01:11:21 +090093 }
Jiyong Park9335a262018-12-24 11:31:58 +090094 }
Jiyong Parkff1458f2018-10-12 21:49:38 +090095
Jaewoong Jung18aefc12020-12-21 09:11:10 -080096 pubKeyName := m.publicKeyFile.Base()[0 : len(m.publicKeyFile.Base())-len(m.publicKeyFile.Ext())]
97 privKeyName := m.privateKeyFile.Base()[0 : len(m.privateKeyFile.Base())-len(m.privateKeyFile.Ext())]
Jiyong Parkff1458f2018-10-12 21:49:38 +090098
Jaewoong Jung939ebd52019-03-26 15:07:36 -070099 if m.properties.Public_key != nil && m.properties.Private_key != nil && pubKeyName != privKeyName {
Jiyong Parkff1458f2018-10-12 21:49:38 +0900100 ctx.ModuleErrorf("public_key %q (keyname:%q) and private_key %q (keyname:%q) do not have same keyname",
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800101 m.publicKeyFile.String(), pubKeyName, m.privateKeyFile, privKeyName)
Jiyong Parkff1458f2018-10-12 21:49:38 +0900102 return
103 }
104 m.keyName = pubKeyName
Jiyong Parkff1458f2018-10-12 21:49:38 +0900105}
Jiyong Park0ca3ce82019-02-18 15:25:04 +0900106
107////////////////////////////////////////////////////////////////////////
108// apex_keys_text
Jiyong Park37eb8bb2019-02-20 22:23:29 +0900109type apexKeysText struct {
110 output android.OutputPath
111}
Jiyong Park0ca3ce82019-02-18 15:25:04 +0900112
113func (s *apexKeysText) GenerateBuildActions(ctx android.SingletonContext) {
Jiyong Park37eb8bb2019-02-20 22:23:29 +0900114 s.output = android.PathForOutput(ctx, "apexkeys.txt")
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900115 type apexKeyEntry struct {
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800116 name string
117 presigned bool
118 publicKey string
119 privateKey string
120 containerCertificate string
121 containerPrivateKey string
122 partition string
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900123 }
124 toString := func(e apexKeyEntry) string {
Colin Crosscf371cc2020-11-13 11:48:42 -0800125 format := "name=%q public_key=%q private_key=%q container_certificate=%q container_private_key=%q partition=%q\n"
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900126 if e.presigned {
127 return fmt.Sprintf(format, e.name, "PRESIGNED", "PRESIGNED", "PRESIGNED", "PRESIGNED", e.partition)
128 } else {
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800129 return fmt.Sprintf(format, e.name, e.publicKey, e.privateKey, e.containerCertificate, e.containerPrivateKey, e.partition)
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900130 }
131 }
132
133 apexKeyMap := make(map[string]apexKeyEntry)
Jiyong Park0ca3ce82019-02-18 15:25:04 +0900134 ctx.VisitAllModules(func(module android.Module) {
Jiyong Park4d277042019-04-23 18:00:10 +0900135 if m, ok := module.(*apexBundle); ok && m.Enabled() && m.installable() {
Jiyong Parkb81b9902020-11-24 19:51:18 +0900136 pem, key := m.getCertificateAndPrivateKey(ctx)
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900137 apexKeyMap[m.Name()] = apexKeyEntry{
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800138 name: m.Name() + ".apex",
139 presigned: false,
140 publicKey: m.publicKeyFile.String(),
141 privateKey: m.privateKeyFile.String(),
142 containerCertificate: pem.String(),
143 containerPrivateKey: key.String(),
144 partition: m.PartitionTag(ctx.DeviceConfig()),
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900145 }
Jiyong Park0ca3ce82019-02-18 15:25:04 +0900146 }
Jiyong Park4d277042019-04-23 18:00:10 +0900147 })
Jiyong Park0ca3ce82019-02-18 15:25:04 +0900148
Jiyong Park4d277042019-04-23 18:00:10 +0900149 // Find prebuilts and let them override apexBundle if they are preferred
150 ctx.VisitAllModules(func(module android.Module) {
151 if m, ok := module.(*Prebuilt); ok && m.Enabled() && m.installable() &&
152 m.Prebuilt().UsePrebuilt() {
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900153 apexKeyMap[m.BaseModuleName()] = apexKeyEntry{
154 name: m.InstallFilename(),
155 presigned: true,
156 partition: m.PartitionTag(ctx.DeviceConfig()),
157 }
158 }
159 })
160
161 // Find apex_set and let them override apexBundle or prebuilts. This is done in a separate pass
162 // so that apex_set are not overridden by prebuilts.
163 ctx.VisitAllModules(func(module android.Module) {
164 if m, ok := module.(*ApexSet); ok && m.Enabled() {
165 entry := apexKeyEntry{
166 name: m.InstallFilename(),
167 presigned: true,
168 partition: m.PartitionTag(ctx.DeviceConfig()),
169 }
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900170 apexKeyMap[m.BaseModuleName()] = entry
Jiyong Park4d277042019-04-23 18:00:10 +0900171 }
172 })
173
174 // iterating over map does not give consistent ordering in golang
175 var moduleNames []string
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900176 for key, _ := range apexKeyMap {
Jiyong Park4d277042019-04-23 18:00:10 +0900177 moduleNames = append(moduleNames, key)
178 }
179 sort.Strings(moduleNames)
180
181 var filecontent strings.Builder
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900182 for _, name := range moduleNames {
Colin Crosscf371cc2020-11-13 11:48:42 -0800183 filecontent.WriteString(toString(apexKeyMap[name]))
Jiyong Park4d277042019-04-23 18:00:10 +0900184 }
Colin Crosscf371cc2020-11-13 11:48:42 -0800185 android.WriteFileRule(ctx, s.output, filecontent.String())
Jiyong Park0ca3ce82019-02-18 15:25:04 +0900186}
187
Jiyong Park0ca3ce82019-02-18 15:25:04 +0900188func apexKeysTextFactory() android.Singleton {
189 return &apexKeysText{}
190}
191
Jiyong Park37eb8bb2019-02-20 22:23:29 +0900192func (s *apexKeysText) MakeVars(ctx android.MakeVarsContext) {
193 ctx.Strict("SOONG_APEX_KEYS_FILE", s.output.String())
Jiyong Park0ca3ce82019-02-18 15:25:04 +0900194}