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