blob: e4214f0e0573a7560f828b320026a250355f59f1 [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 Parkff1458f2018-10-12 21:49:38 +090019
20 "android/soong/android"
21 "github.com/google/blueprint/proptools"
22)
23
24var String = proptools.String
25
26func init() {
Paul Duffin667893c2021-03-09 22:34:13 +000027 registerApexKeyBuildComponents(android.InitRegistrationContext)
28}
29
30func registerApexKeyBuildComponents(ctx android.RegistrationContext) {
31 ctx.RegisterModuleType("apex_key", ApexKeyFactory)
Jiyong Parkff1458f2018-10-12 21:49:38 +090032}
33
34type apexKey struct {
35 android.ModuleBase
36
37 properties apexKeyProperties
38
Jaewoong Jung18aefc12020-12-21 09:11:10 -080039 publicKeyFile android.Path
40 privateKeyFile android.Path
Jiyong Parkff1458f2018-10-12 21:49:38 +090041}
42
43type apexKeyProperties struct {
Jiyong Park67882562019-03-21 01:11:21 +090044 // Path or module to the public key file in avbpubkey format. Installed to the device.
Jiyong Parkff1458f2018-10-12 21:49:38 +090045 // Base name of the file is used as the ID for the key.
Jiyong Park67882562019-03-21 01:11:21 +090046 Public_key *string `android:"path"`
47 // Path or module to the private key file in pem format. Used to sign APEXs.
48 Private_key *string `android:"path"`
Jiyong Park50d99202018-12-27 13:32:34 +090049
50 // Whether this key is installable to one of the partitions. Defualt: true.
51 Installable *bool
Jiyong Parkff1458f2018-10-12 21:49:38 +090052}
53
Jiyong Parkd1063c12019-07-17 20:08:41 +090054func ApexKeyFactory() android.Module {
Jiyong Parkff1458f2018-10-12 21:49:38 +090055 module := &apexKey{}
56 module.AddProperties(&module.properties)
Jooyung Han8d4a1f02023-08-23 13:54:08 +090057 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
Jiyong Parkff1458f2018-10-12 21:49:38 +090058 return module
59}
60
Jiyong Park50d99202018-12-27 13:32:34 +090061func (m *apexKey) installable() bool {
Jiyong Park42cca6c2019-04-01 11:15:50 +090062 return false
Jiyong Park50d99202018-12-27 13:32:34 +090063}
64
Jiyong Parkff1458f2018-10-12 21:49:38 +090065func (m *apexKey) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jiyong Park67882562019-03-21 01:11:21 +090066 // If the keys are from other modules (i.e. :module syntax) respect it.
67 // Otherwise, try to locate the key files in the default cert dir or
68 // in the local module dir
69 if android.SrcIsModule(String(m.properties.Public_key)) != "" {
Jaewoong Jung18aefc12020-12-21 09:11:10 -080070 m.publicKeyFile = android.PathForModuleSrc(ctx, String(m.properties.Public_key))
Jiyong Park67882562019-03-21 01:11:21 +090071 } else {
Jaewoong Jung18aefc12020-12-21 09:11:10 -080072 m.publicKeyFile = ctx.Config().ApexKeyDir(ctx).Join(ctx, String(m.properties.Public_key))
Jiyong Park67882562019-03-21 01:11:21 +090073 // If not found, fall back to the local key pairs
Jaewoong Jung18aefc12020-12-21 09:11:10 -080074 if !android.ExistentPathForSource(ctx, m.publicKeyFile.String()).Valid() {
75 m.publicKeyFile = android.PathForModuleSrc(ctx, String(m.properties.Public_key))
Jiyong Park67882562019-03-21 01:11:21 +090076 }
Jiyong Park9335a262018-12-24 11:31:58 +090077 }
Jiyong Park67882562019-03-21 01:11:21 +090078
79 if android.SrcIsModule(String(m.properties.Private_key)) != "" {
Jaewoong Jung18aefc12020-12-21 09:11:10 -080080 m.privateKeyFile = android.PathForModuleSrc(ctx, String(m.properties.Private_key))
Jiyong Park67882562019-03-21 01:11:21 +090081 } else {
Jaewoong Jung18aefc12020-12-21 09:11:10 -080082 m.privateKeyFile = ctx.Config().ApexKeyDir(ctx).Join(ctx, String(m.properties.Private_key))
83 if !android.ExistentPathForSource(ctx, m.privateKeyFile.String()).Valid() {
84 m.privateKeyFile = android.PathForModuleSrc(ctx, String(m.properties.Private_key))
Jiyong Park67882562019-03-21 01:11:21 +090085 }
Jiyong Park9335a262018-12-24 11:31:58 +090086 }
Jiyong Parkff1458f2018-10-12 21:49:38 +090087
Jaewoong Jung18aefc12020-12-21 09:11:10 -080088 pubKeyName := m.publicKeyFile.Base()[0 : len(m.publicKeyFile.Base())-len(m.publicKeyFile.Ext())]
89 privKeyName := m.privateKeyFile.Base()[0 : len(m.privateKeyFile.Base())-len(m.privateKeyFile.Ext())]
Jiyong Parkff1458f2018-10-12 21:49:38 +090090
Jaewoong Jung939ebd52019-03-26 15:07:36 -070091 if m.properties.Public_key != nil && m.properties.Private_key != nil && pubKeyName != privKeyName {
Jiyong Parkff1458f2018-10-12 21:49:38 +090092 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 -080093 m.publicKeyFile.String(), pubKeyName, m.privateKeyFile, privKeyName)
Jiyong Parkff1458f2018-10-12 21:49:38 +090094 return
95 }
Jiyong Parkff1458f2018-10-12 21:49:38 +090096}
Jiyong Park0ca3ce82019-02-18 15:25:04 +090097
Jooyung Han2cf35e72023-10-30 11:17:16 +090098type apexKeyEntry struct {
99 name string
100 presigned bool
101 publicKey string
102 privateKey string
103 containerCertificate string
104 containerPrivateKey string
105 partition string
106 signTool string
107}
108
109func (e apexKeyEntry) String() string {
110 signTool := ""
111 if e.signTool != "" {
112 signTool = fmt.Sprintf(" sign_tool=%q", e.signTool)
113 }
114 format := "name=%q public_key=%q private_key=%q container_certificate=%q container_private_key=%q partition=%q%s\n"
115 if e.presigned {
116 return fmt.Sprintf(format, e.name, "PRESIGNED", "PRESIGNED", "PRESIGNED", "PRESIGNED", e.partition, signTool)
117 } else {
118 return fmt.Sprintf(format, e.name, e.publicKey, e.privateKey, e.containerCertificate, e.containerPrivateKey, e.partition, signTool)
119 }
120}
121
Jooyung Han286957d2023-10-30 16:17:56 +0900122func apexKeyEntryFor(ctx android.ModuleContext, module android.Module) apexKeyEntry {
Jooyung Han2cf35e72023-10-30 11:17:16 +0900123 switch m := module.(type) {
124 case *apexBundle:
125 pem, key := m.getCertificateAndPrivateKey(ctx)
126 return apexKeyEntry{
127 name: m.Name() + ".apex",
128 presigned: false,
129 publicKey: m.publicKeyFile.String(),
130 privateKey: m.privateKeyFile.String(),
131 containerCertificate: pem.String(),
132 containerPrivateKey: key.String(),
133 partition: m.PartitionTag(ctx.DeviceConfig()),
134 signTool: proptools.String(m.properties.Custom_sign_tool),
135 }
136 case *Prebuilt:
137 return apexKeyEntry{
138 name: m.InstallFilename(),
139 presigned: true,
140 partition: m.PartitionTag(ctx.DeviceConfig()),
141 }
142 case *ApexSet:
143 return apexKeyEntry{
144 name: m.InstallFilename(),
145 presigned: true,
146 partition: m.PartitionTag(ctx.DeviceConfig()),
147 }
148 }
149 panic(fmt.Errorf("unknown type(%t) for apexKeyEntry", module))
150}
151
Jooyung Han286957d2023-10-30 16:17:56 +0900152func writeApexKeys(ctx android.ModuleContext, module android.Module) android.WritablePath {
153 path := android.PathForModuleOut(ctx, "apexkeys.txt")
154 entry := apexKeyEntryFor(ctx, module)
155 android.WriteFileRuleVerbatim(ctx, path, entry.String())
156 return path
Jiyong Park0ca3ce82019-02-18 15:25:04 +0900157}