xref: /aosp_15_r20/build/soong/apex/key.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright (C) 2018 The Android Open Source Project
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage apex
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"fmt"
19*333d2b36SAndroid Build Coastguard Worker
20*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
21*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
22*333d2b36SAndroid Build Coastguard Worker)
23*333d2b36SAndroid Build Coastguard Worker
24*333d2b36SAndroid Build Coastguard Workervar String = proptools.String
25*333d2b36SAndroid Build Coastguard Worker
26*333d2b36SAndroid Build Coastguard Workerfunc init() {
27*333d2b36SAndroid Build Coastguard Worker	registerApexKeyBuildComponents(android.InitRegistrationContext)
28*333d2b36SAndroid Build Coastguard Worker}
29*333d2b36SAndroid Build Coastguard Worker
30*333d2b36SAndroid Build Coastguard Workerfunc registerApexKeyBuildComponents(ctx android.RegistrationContext) {
31*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("apex_key", ApexKeyFactory)
32*333d2b36SAndroid Build Coastguard Worker}
33*333d2b36SAndroid Build Coastguard Worker
34*333d2b36SAndroid Build Coastguard Workertype apexKey struct {
35*333d2b36SAndroid Build Coastguard Worker	android.ModuleBase
36*333d2b36SAndroid Build Coastguard Worker
37*333d2b36SAndroid Build Coastguard Worker	properties apexKeyProperties
38*333d2b36SAndroid Build Coastguard Worker
39*333d2b36SAndroid Build Coastguard Worker	publicKeyFile  android.Path
40*333d2b36SAndroid Build Coastguard Worker	privateKeyFile android.Path
41*333d2b36SAndroid Build Coastguard Worker}
42*333d2b36SAndroid Build Coastguard Worker
43*333d2b36SAndroid Build Coastguard Workertype apexKeyProperties struct {
44*333d2b36SAndroid Build Coastguard Worker	// Path or module to the public key file in avbpubkey format. Installed to the device.
45*333d2b36SAndroid Build Coastguard Worker	// Base name of the file is used as the ID for the key.
46*333d2b36SAndroid Build Coastguard Worker	Public_key *string `android:"path"`
47*333d2b36SAndroid Build Coastguard Worker	// Path or module to the private key file in pem format. Used to sign APEXs.
48*333d2b36SAndroid Build Coastguard Worker	Private_key *string `android:"path"`
49*333d2b36SAndroid Build Coastguard Worker
50*333d2b36SAndroid Build Coastguard Worker	// Whether this key is installable to one of the partitions. Defualt: true.
51*333d2b36SAndroid Build Coastguard Worker	Installable *bool
52*333d2b36SAndroid Build Coastguard Worker}
53*333d2b36SAndroid Build Coastguard Worker
54*333d2b36SAndroid Build Coastguard Workerfunc ApexKeyFactory() android.Module {
55*333d2b36SAndroid Build Coastguard Worker	module := &apexKey{}
56*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.properties)
57*333d2b36SAndroid Build Coastguard Worker	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
58*333d2b36SAndroid Build Coastguard Worker	return module
59*333d2b36SAndroid Build Coastguard Worker}
60*333d2b36SAndroid Build Coastguard Worker
61*333d2b36SAndroid Build Coastguard Workerfunc (m *apexKey) installable() bool {
62*333d2b36SAndroid Build Coastguard Worker	return false
63*333d2b36SAndroid Build Coastguard Worker}
64*333d2b36SAndroid Build Coastguard Worker
65*333d2b36SAndroid Build Coastguard Workerfunc (m *apexKey) GenerateAndroidBuildActions(ctx android.ModuleContext) {
66*333d2b36SAndroid Build Coastguard Worker	// If the keys are from other modules (i.e. :module syntax) respect it.
67*333d2b36SAndroid Build Coastguard Worker	// Otherwise, try to locate the key files in the default cert dir or
68*333d2b36SAndroid Build Coastguard Worker	// in the local module dir
69*333d2b36SAndroid Build Coastguard Worker	if android.SrcIsModule(String(m.properties.Public_key)) != "" {
70*333d2b36SAndroid Build Coastguard Worker		m.publicKeyFile = android.PathForModuleSrc(ctx, String(m.properties.Public_key))
71*333d2b36SAndroid Build Coastguard Worker	} else {
72*333d2b36SAndroid Build Coastguard Worker		m.publicKeyFile = ctx.Config().ApexKeyDir(ctx).Join(ctx, String(m.properties.Public_key))
73*333d2b36SAndroid Build Coastguard Worker		// If not found, fall back to the local key pairs
74*333d2b36SAndroid Build Coastguard Worker		if !android.ExistentPathForSource(ctx, m.publicKeyFile.String()).Valid() {
75*333d2b36SAndroid Build Coastguard Worker			m.publicKeyFile = android.PathForModuleSrc(ctx, String(m.properties.Public_key))
76*333d2b36SAndroid Build Coastguard Worker		}
77*333d2b36SAndroid Build Coastguard Worker	}
78*333d2b36SAndroid Build Coastguard Worker
79*333d2b36SAndroid Build Coastguard Worker	if android.SrcIsModule(String(m.properties.Private_key)) != "" {
80*333d2b36SAndroid Build Coastguard Worker		m.privateKeyFile = android.PathForModuleSrc(ctx, String(m.properties.Private_key))
81*333d2b36SAndroid Build Coastguard Worker	} else {
82*333d2b36SAndroid Build Coastguard Worker		m.privateKeyFile = ctx.Config().ApexKeyDir(ctx).Join(ctx, String(m.properties.Private_key))
83*333d2b36SAndroid Build Coastguard Worker		if !android.ExistentPathForSource(ctx, m.privateKeyFile.String()).Valid() {
84*333d2b36SAndroid Build Coastguard Worker			m.privateKeyFile = android.PathForModuleSrc(ctx, String(m.properties.Private_key))
85*333d2b36SAndroid Build Coastguard Worker		}
86*333d2b36SAndroid Build Coastguard Worker	}
87*333d2b36SAndroid Build Coastguard Worker
88*333d2b36SAndroid Build Coastguard Worker	pubKeyName := m.publicKeyFile.Base()[0 : len(m.publicKeyFile.Base())-len(m.publicKeyFile.Ext())]
89*333d2b36SAndroid Build Coastguard Worker	privKeyName := m.privateKeyFile.Base()[0 : len(m.privateKeyFile.Base())-len(m.privateKeyFile.Ext())]
90*333d2b36SAndroid Build Coastguard Worker
91*333d2b36SAndroid Build Coastguard Worker	if m.properties.Public_key != nil && m.properties.Private_key != nil && pubKeyName != privKeyName {
92*333d2b36SAndroid Build Coastguard Worker		ctx.ModuleErrorf("public_key %q (keyname:%q) and private_key %q (keyname:%q) do not have same keyname",
93*333d2b36SAndroid Build Coastguard Worker			m.publicKeyFile.String(), pubKeyName, m.privateKeyFile, privKeyName)
94*333d2b36SAndroid Build Coastguard Worker		return
95*333d2b36SAndroid Build Coastguard Worker	}
96*333d2b36SAndroid Build Coastguard Worker}
97*333d2b36SAndroid Build Coastguard Worker
98*333d2b36SAndroid Build Coastguard Workertype apexKeyEntry struct {
99*333d2b36SAndroid Build Coastguard Worker	name                 string
100*333d2b36SAndroid Build Coastguard Worker	presigned            bool
101*333d2b36SAndroid Build Coastguard Worker	publicKey            string
102*333d2b36SAndroid Build Coastguard Worker	privateKey           string
103*333d2b36SAndroid Build Coastguard Worker	containerCertificate string
104*333d2b36SAndroid Build Coastguard Worker	containerPrivateKey  string
105*333d2b36SAndroid Build Coastguard Worker	partition            string
106*333d2b36SAndroid Build Coastguard Worker	signTool             string
107*333d2b36SAndroid Build Coastguard Worker}
108*333d2b36SAndroid Build Coastguard Worker
109*333d2b36SAndroid Build Coastguard Workerfunc (e apexKeyEntry) String() string {
110*333d2b36SAndroid Build Coastguard Worker	signTool := ""
111*333d2b36SAndroid Build Coastguard Worker	if e.signTool != "" {
112*333d2b36SAndroid Build Coastguard Worker		signTool = fmt.Sprintf(" sign_tool=%q", e.signTool)
113*333d2b36SAndroid Build Coastguard Worker	}
114*333d2b36SAndroid Build Coastguard Worker	format := "name=%q public_key=%q private_key=%q container_certificate=%q container_private_key=%q partition=%q%s\n"
115*333d2b36SAndroid Build Coastguard Worker	if e.presigned {
116*333d2b36SAndroid Build Coastguard Worker		return fmt.Sprintf(format, e.name, "PRESIGNED", "PRESIGNED", "PRESIGNED", "PRESIGNED", e.partition, signTool)
117*333d2b36SAndroid Build Coastguard Worker	} else {
118*333d2b36SAndroid Build Coastguard Worker		return fmt.Sprintf(format, e.name, e.publicKey, e.privateKey, e.containerCertificate, e.containerPrivateKey, e.partition, signTool)
119*333d2b36SAndroid Build Coastguard Worker	}
120*333d2b36SAndroid Build Coastguard Worker}
121*333d2b36SAndroid Build Coastguard Worker
122*333d2b36SAndroid Build Coastguard Workerfunc apexKeyEntryFor(ctx android.ModuleContext, module android.Module) apexKeyEntry {
123*333d2b36SAndroid Build Coastguard Worker	switch m := module.(type) {
124*333d2b36SAndroid Build Coastguard Worker	case *apexBundle:
125*333d2b36SAndroid Build Coastguard Worker		pem, key := m.getCertificateAndPrivateKey(ctx)
126*333d2b36SAndroid Build Coastguard Worker		return apexKeyEntry{
127*333d2b36SAndroid Build Coastguard Worker			name:                 m.Name() + ".apex",
128*333d2b36SAndroid Build Coastguard Worker			presigned:            false,
129*333d2b36SAndroid Build Coastguard Worker			publicKey:            m.publicKeyFile.String(),
130*333d2b36SAndroid Build Coastguard Worker			privateKey:           m.privateKeyFile.String(),
131*333d2b36SAndroid Build Coastguard Worker			containerCertificate: pem.String(),
132*333d2b36SAndroid Build Coastguard Worker			containerPrivateKey:  key.String(),
133*333d2b36SAndroid Build Coastguard Worker			partition:            m.PartitionTag(ctx.DeviceConfig()),
134*333d2b36SAndroid Build Coastguard Worker			signTool:             proptools.String(m.properties.Custom_sign_tool),
135*333d2b36SAndroid Build Coastguard Worker		}
136*333d2b36SAndroid Build Coastguard Worker	case *Prebuilt:
137*333d2b36SAndroid Build Coastguard Worker		return apexKeyEntry{
138*333d2b36SAndroid Build Coastguard Worker			name:      m.InstallFilename(),
139*333d2b36SAndroid Build Coastguard Worker			presigned: true,
140*333d2b36SAndroid Build Coastguard Worker			partition: m.PartitionTag(ctx.DeviceConfig()),
141*333d2b36SAndroid Build Coastguard Worker		}
142*333d2b36SAndroid Build Coastguard Worker	case *ApexSet:
143*333d2b36SAndroid Build Coastguard Worker		return apexKeyEntry{
144*333d2b36SAndroid Build Coastguard Worker			name:      m.InstallFilename(),
145*333d2b36SAndroid Build Coastguard Worker			presigned: true,
146*333d2b36SAndroid Build Coastguard Worker			partition: m.PartitionTag(ctx.DeviceConfig()),
147*333d2b36SAndroid Build Coastguard Worker		}
148*333d2b36SAndroid Build Coastguard Worker	}
149*333d2b36SAndroid Build Coastguard Worker	panic(fmt.Errorf("unknown type(%t) for apexKeyEntry", module))
150*333d2b36SAndroid Build Coastguard Worker}
151*333d2b36SAndroid Build Coastguard Worker
152*333d2b36SAndroid Build Coastguard Workerfunc writeApexKeys(ctx android.ModuleContext, module android.Module) android.WritablePath {
153*333d2b36SAndroid Build Coastguard Worker	path := android.PathForModuleOut(ctx, "apexkeys.txt")
154*333d2b36SAndroid Build Coastguard Worker	entry := apexKeyEntryFor(ctx, module)
155*333d2b36SAndroid Build Coastguard Worker	android.WriteFileRuleVerbatim(ctx, path, entry.String())
156*333d2b36SAndroid Build Coastguard Worker	return path
157*333d2b36SAndroid Build Coastguard Worker}
158