blob: fc1456b961464358c1dd7cd5862302345bf30448 [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"
Rupert Shuttlewortheb8c85a2021-07-27 07:10:32 -040023 "android/soong/bazel"
Colin Cross5f692ec2019-02-01 16:53:07 -080024
Jiyong Parkff1458f2018-10-12 21:49:38 +090025 "github.com/google/blueprint/proptools"
26)
27
28var String = proptools.String
29
30func init() {
Paul Duffin667893c2021-03-09 22:34:13 +000031 registerApexKeyBuildComponents(android.InitRegistrationContext)
32}
33
34func registerApexKeyBuildComponents(ctx android.RegistrationContext) {
35 ctx.RegisterModuleType("apex_key", ApexKeyFactory)
LaMont Jones0c10e4d2023-05-16 00:58:37 +000036 ctx.RegisterParallelSingletonType("apex_keys_text", apexKeysTextFactory)
Jiyong Parkff1458f2018-10-12 21:49:38 +090037}
38
39type apexKey struct {
40 android.ModuleBase
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -040041 android.BazelModuleBase
Jiyong Parkff1458f2018-10-12 21:49:38 +090042
43 properties apexKeyProperties
44
Jaewoong Jung18aefc12020-12-21 09:11:10 -080045 publicKeyFile android.Path
46 privateKeyFile android.Path
Jiyong Parkff1458f2018-10-12 21:49:38 +090047}
48
49type apexKeyProperties struct {
Jiyong Park67882562019-03-21 01:11:21 +090050 // Path or module to the public key file in avbpubkey format. Installed to the device.
Jiyong Parkff1458f2018-10-12 21:49:38 +090051 // Base name of the file is used as the ID for the key.
Jiyong Park67882562019-03-21 01:11:21 +090052 Public_key *string `android:"path"`
53 // Path or module to the private key file in pem format. Used to sign APEXs.
54 Private_key *string `android:"path"`
Jiyong Park50d99202018-12-27 13:32:34 +090055
56 // Whether this key is installable to one of the partitions. Defualt: true.
57 Installable *bool
Jiyong Parkff1458f2018-10-12 21:49:38 +090058}
59
Jiyong Parkd1063c12019-07-17 20:08:41 +090060func ApexKeyFactory() android.Module {
Jiyong Parkff1458f2018-10-12 21:49:38 +090061 module := &apexKey{}
62 module.AddProperties(&module.properties)
Jooyung Han8d4a1f02023-08-23 13:54:08 +090063 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -040064 android.InitBazelModule(module)
Jiyong Parkff1458f2018-10-12 21:49:38 +090065 return module
66}
67
Jiyong Park50d99202018-12-27 13:32:34 +090068func (m *apexKey) installable() bool {
Jiyong Park42cca6c2019-04-01 11:15:50 +090069 return false
Jiyong Park50d99202018-12-27 13:32:34 +090070}
71
Jiyong Parkff1458f2018-10-12 21:49:38 +090072func (m *apexKey) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jiyong Park67882562019-03-21 01:11:21 +090073 // If the keys are from other modules (i.e. :module syntax) respect it.
74 // Otherwise, try to locate the key files in the default cert dir or
75 // in the local module dir
76 if android.SrcIsModule(String(m.properties.Public_key)) != "" {
Jaewoong Jung18aefc12020-12-21 09:11:10 -080077 m.publicKeyFile = android.PathForModuleSrc(ctx, String(m.properties.Public_key))
Jiyong Park67882562019-03-21 01:11:21 +090078 } else {
Jaewoong Jung18aefc12020-12-21 09:11:10 -080079 m.publicKeyFile = ctx.Config().ApexKeyDir(ctx).Join(ctx, String(m.properties.Public_key))
Jiyong Park67882562019-03-21 01:11:21 +090080 // If not found, fall back to the local key pairs
Jaewoong Jung18aefc12020-12-21 09:11:10 -080081 if !android.ExistentPathForSource(ctx, m.publicKeyFile.String()).Valid() {
82 m.publicKeyFile = android.PathForModuleSrc(ctx, String(m.properties.Public_key))
Jiyong Park67882562019-03-21 01:11:21 +090083 }
Jiyong Park9335a262018-12-24 11:31:58 +090084 }
Jiyong Park67882562019-03-21 01:11:21 +090085
86 if android.SrcIsModule(String(m.properties.Private_key)) != "" {
Jaewoong Jung18aefc12020-12-21 09:11:10 -080087 m.privateKeyFile = android.PathForModuleSrc(ctx, String(m.properties.Private_key))
Jiyong Park67882562019-03-21 01:11:21 +090088 } else {
Jaewoong Jung18aefc12020-12-21 09:11:10 -080089 m.privateKeyFile = ctx.Config().ApexKeyDir(ctx).Join(ctx, String(m.properties.Private_key))
90 if !android.ExistentPathForSource(ctx, m.privateKeyFile.String()).Valid() {
91 m.privateKeyFile = android.PathForModuleSrc(ctx, String(m.properties.Private_key))
Jiyong Park67882562019-03-21 01:11:21 +090092 }
Jiyong Park9335a262018-12-24 11:31:58 +090093 }
Jiyong Parkff1458f2018-10-12 21:49:38 +090094
Jaewoong Jung18aefc12020-12-21 09:11:10 -080095 pubKeyName := m.publicKeyFile.Base()[0 : len(m.publicKeyFile.Base())-len(m.publicKeyFile.Ext())]
96 privKeyName := m.privateKeyFile.Base()[0 : len(m.privateKeyFile.Base())-len(m.privateKeyFile.Ext())]
Jiyong Parkff1458f2018-10-12 21:49:38 +090097
Jaewoong Jung939ebd52019-03-26 15:07:36 -070098 if m.properties.Public_key != nil && m.properties.Private_key != nil && pubKeyName != privKeyName {
Jiyong Parkff1458f2018-10-12 21:49:38 +090099 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 -0800100 m.publicKeyFile.String(), pubKeyName, m.privateKeyFile, privKeyName)
Jiyong Parkff1458f2018-10-12 21:49:38 +0900101 return
102 }
Jiyong Parkff1458f2018-10-12 21:49:38 +0900103}
Jiyong Park0ca3ce82019-02-18 15:25:04 +0900104
Colin Crossd079e0b2022-08-16 10:27:33 -0700105// //////////////////////////////////////////////////////////////////////
Jiyong Park0ca3ce82019-02-18 15:25:04 +0900106// apex_keys_text
Jiyong Park37eb8bb2019-02-20 22:23:29 +0900107type apexKeysText struct {
108 output android.OutputPath
109}
Jiyong Park0ca3ce82019-02-18 15:25:04 +0900110
111func (s *apexKeysText) GenerateBuildActions(ctx android.SingletonContext) {
Jiyong Park37eb8bb2019-02-20 22:23:29 +0900112 s.output = android.PathForOutput(ctx, "apexkeys.txt")
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900113 type apexKeyEntry struct {
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800114 name string
115 presigned bool
116 publicKey string
117 privateKey string
118 containerCertificate string
119 containerPrivateKey string
120 partition string
Jooyung Han09c11ad2021-10-27 03:45:31 +0900121 signTool string
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900122 }
123 toString := func(e apexKeyEntry) string {
Jooyung Han09c11ad2021-10-27 03:45:31 +0900124 signTool := ""
125 if e.signTool != "" {
126 signTool = fmt.Sprintf(" sign_tool=%q", e.signTool)
127 }
128 format := "name=%q public_key=%q private_key=%q container_certificate=%q container_private_key=%q partition=%q%s\n"
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900129 if e.presigned {
Jooyung Han09c11ad2021-10-27 03:45:31 +0900130 return fmt.Sprintf(format, e.name, "PRESIGNED", "PRESIGNED", "PRESIGNED", "PRESIGNED", e.partition, signTool)
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900131 } else {
Jooyung Han09c11ad2021-10-27 03:45:31 +0900132 return fmt.Sprintf(format, e.name, e.publicKey, e.privateKey, e.containerCertificate, e.containerPrivateKey, e.partition, signTool)
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900133 }
134 }
135
136 apexKeyMap := make(map[string]apexKeyEntry)
Jiyong Park0ca3ce82019-02-18 15:25:04 +0900137 ctx.VisitAllModules(func(module android.Module) {
Jiyong Park4d277042019-04-23 18:00:10 +0900138 if m, ok := module.(*apexBundle); ok && m.Enabled() && m.installable() {
Jiyong Parkb81b9902020-11-24 19:51:18 +0900139 pem, key := m.getCertificateAndPrivateKey(ctx)
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900140 apexKeyMap[m.Name()] = apexKeyEntry{
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800141 name: m.Name() + ".apex",
142 presigned: false,
143 publicKey: m.publicKeyFile.String(),
144 privateKey: m.privateKeyFile.String(),
145 containerCertificate: pem.String(),
146 containerPrivateKey: key.String(),
147 partition: m.PartitionTag(ctx.DeviceConfig()),
Jooyung Han09c11ad2021-10-27 03:45:31 +0900148 signTool: proptools.String(m.properties.Custom_sign_tool),
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900149 }
Jiyong Park0ca3ce82019-02-18 15:25:04 +0900150 }
Jiyong Park4d277042019-04-23 18:00:10 +0900151 })
Jiyong Park0ca3ce82019-02-18 15:25:04 +0900152
Jiyong Park4d277042019-04-23 18:00:10 +0900153 // Find prebuilts and let them override apexBundle if they are preferred
154 ctx.VisitAllModules(func(module android.Module) {
155 if m, ok := module.(*Prebuilt); ok && m.Enabled() && m.installable() &&
156 m.Prebuilt().UsePrebuilt() {
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900157 apexKeyMap[m.BaseModuleName()] = apexKeyEntry{
158 name: m.InstallFilename(),
159 presigned: true,
160 partition: m.PartitionTag(ctx.DeviceConfig()),
161 }
162 }
163 })
164
165 // Find apex_set and let them override apexBundle or prebuilts. This is done in a separate pass
166 // so that apex_set are not overridden by prebuilts.
167 ctx.VisitAllModules(func(module android.Module) {
168 if m, ok := module.(*ApexSet); ok && m.Enabled() {
169 entry := apexKeyEntry{
170 name: m.InstallFilename(),
171 presigned: true,
172 partition: m.PartitionTag(ctx.DeviceConfig()),
173 }
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900174 apexKeyMap[m.BaseModuleName()] = entry
Jiyong Park4d277042019-04-23 18:00:10 +0900175 }
176 })
177
178 // iterating over map does not give consistent ordering in golang
179 var moduleNames []string
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900180 for key, _ := range apexKeyMap {
Jiyong Park4d277042019-04-23 18:00:10 +0900181 moduleNames = append(moduleNames, key)
182 }
183 sort.Strings(moduleNames)
184
185 var filecontent strings.Builder
Jiyong Park8d6c51e2020-06-12 17:26:31 +0900186 for _, name := range moduleNames {
Colin Crosscf371cc2020-11-13 11:48:42 -0800187 filecontent.WriteString(toString(apexKeyMap[name]))
Jiyong Park4d277042019-04-23 18:00:10 +0900188 }
Colin Crosscf371cc2020-11-13 11:48:42 -0800189 android.WriteFileRule(ctx, s.output, filecontent.String())
Jiyong Park0ca3ce82019-02-18 15:25:04 +0900190}
191
Jiyong Park0ca3ce82019-02-18 15:25:04 +0900192func apexKeysTextFactory() android.Singleton {
193 return &apexKeysText{}
194}
195
Jiyong Park37eb8bb2019-02-20 22:23:29 +0900196func (s *apexKeysText) MakeVars(ctx android.MakeVarsContext) {
197 ctx.Strict("SOONG_APEX_KEYS_FILE", s.output.String())
Jiyong Park0ca3ce82019-02-18 15:25:04 +0900198}
Rupert Shuttlewortheb8c85a2021-07-27 07:10:32 -0400199
200// For Bazel / bp2build
201
202type bazelApexKeyAttributes struct {
Jingwen Chen1d873332022-10-05 06:15:15 +0000203 Public_key bazel.LabelAttribute
Jingwen Chen6817bbb2022-10-14 09:56:07 +0000204 Public_key_name bazel.StringAttribute
Jingwen Chen1d873332022-10-05 06:15:15 +0000205
206 Private_key bazel.LabelAttribute
Jingwen Chen6817bbb2022-10-14 09:56:07 +0000207 Private_key_name bazel.StringAttribute
Rupert Shuttlewortheb8c85a2021-07-27 07:10:32 -0400208}
209
Liz Kammerbe46fcc2021-11-01 15:32:43 -0400210// ConvertWithBp2build performs conversion apexKey for bp2build
Chris Parsons637458d2023-09-19 20:09:00 +0000211func (m *apexKey) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
Liz Kammerbe46fcc2021-11-01 15:32:43 -0400212 apexKeyBp2BuildInternal(ctx, m)
Rupert Shuttlewortheb8c85a2021-07-27 07:10:32 -0400213}
214
Chris Parsons637458d2023-09-19 20:09:00 +0000215func apexKeyBp2BuildInternal(ctx android.Bp2buildMutatorContext, module *apexKey) {
Jingwen Chen6817bbb2022-10-14 09:56:07 +0000216 privateKeyLabelAttribute, privateKeyNameAttribute :=
217 android.BazelStringOrLabelFromProp(ctx, module.properties.Private_key)
Rupert Shuttlewortheb8c85a2021-07-27 07:10:32 -0400218
Jingwen Chen6817bbb2022-10-14 09:56:07 +0000219 publicKeyLabelAttribute, publicKeyNameAttribute :=
220 android.BazelStringOrLabelFromProp(ctx, module.properties.Public_key)
Rupert Shuttlewortheb8c85a2021-07-27 07:10:32 -0400221
222 attrs := &bazelApexKeyAttributes{
Jingwen Chen1d873332022-10-05 06:15:15 +0000223 Private_key: privateKeyLabelAttribute,
224 Private_key_name: privateKeyNameAttribute,
225
226 Public_key: publicKeyLabelAttribute,
227 Public_key_name: publicKeyNameAttribute,
Rupert Shuttlewortheb8c85a2021-07-27 07:10:32 -0400228 }
229
230 props := bazel.BazelTargetModuleProperties{
231 Rule_class: "apex_key",
Cole Faust5f90da32022-04-29 13:37:43 -0700232 Bzl_load_location: "//build/bazel/rules/apex:apex_key.bzl",
Rupert Shuttlewortheb8c85a2021-07-27 07:10:32 -0400233 }
234
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux447f6c92021-08-31 20:30:36 +0000235 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs)
Rupert Shuttlewortheb8c85a2021-07-27 07:10:32 -0400236}