1*7594170eSAndroid Build Coastguard Worker# Copyright (C) 2021 The Android Open Source Project 2*7594170eSAndroid Build Coastguard Worker# 3*7594170eSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*7594170eSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*7594170eSAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*7594170eSAndroid Build Coastguard Worker# 7*7594170eSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*7594170eSAndroid Build Coastguard Worker# 9*7594170eSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*7594170eSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*7594170eSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*7594170eSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*7594170eSAndroid Build Coastguard Worker# limitations under the License. 14*7594170eSAndroid Build Coastguard Worker 15*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:paths.bzl", "paths") 16*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") 17*7594170eSAndroid Build Coastguard Worker 18*7594170eSAndroid Build Coastguard WorkerAndroidAppCertificateInfo = provider( 19*7594170eSAndroid Build Coastguard Worker "Info needed for Android app certificates", 20*7594170eSAndroid Build Coastguard Worker fields = { 21*7594170eSAndroid Build Coastguard Worker "pem": "Certificate .pem file", 22*7594170eSAndroid Build Coastguard Worker "pk8": "Certificate .pk8 file", 23*7594170eSAndroid Build Coastguard Worker "key_name": "Key name", 24*7594170eSAndroid Build Coastguard Worker }, 25*7594170eSAndroid Build Coastguard Worker) 26*7594170eSAndroid Build Coastguard Worker 27*7594170eSAndroid Build Coastguard WorkerNoAndroidAppCertificateInfo = provider( 28*7594170eSAndroid Build Coastguard Worker "A provider that indicates this target is NOT an android app certificate. It's used as the default value for an apex's certificate override.", 29*7594170eSAndroid Build Coastguard Worker) 30*7594170eSAndroid Build Coastguard Worker 31*7594170eSAndroid Build Coastguard Workerdef _no_android_app_certificate_rule_impl(_ctx): 32*7594170eSAndroid Build Coastguard Worker return [NoAndroidAppCertificateInfo()] 33*7594170eSAndroid Build Coastguard Worker 34*7594170eSAndroid Build Coastguard Workerno_android_app_certificate = rule( 35*7594170eSAndroid Build Coastguard Worker implementation = _no_android_app_certificate_rule_impl, 36*7594170eSAndroid Build Coastguard Worker) 37*7594170eSAndroid Build Coastguard Worker 38*7594170eSAndroid Build Coastguard Workerdef _android_app_certificate_rule_impl(ctx): 39*7594170eSAndroid Build Coastguard Worker cert_name = ctx.attr.certificate 40*7594170eSAndroid Build Coastguard Worker pk8 = ctx.file.pk8 41*7594170eSAndroid Build Coastguard Worker pem = ctx.file.pem 42*7594170eSAndroid Build Coastguard Worker 43*7594170eSAndroid Build Coastguard Worker return [ 44*7594170eSAndroid Build Coastguard Worker AndroidAppCertificateInfo(pem = pem, pk8 = pk8, key_name = cert_name), 45*7594170eSAndroid Build Coastguard Worker ] 46*7594170eSAndroid Build Coastguard Worker 47*7594170eSAndroid Build Coastguard Worker_android_app_certificate = rule( 48*7594170eSAndroid Build Coastguard Worker implementation = _android_app_certificate_rule_impl, 49*7594170eSAndroid Build Coastguard Worker attrs = { 50*7594170eSAndroid Build Coastguard Worker "pem": attr.label(mandatory = True, allow_single_file = [".pem"]), 51*7594170eSAndroid Build Coastguard Worker "pk8": attr.label(mandatory = True, allow_single_file = [".pk8"]), 52*7594170eSAndroid Build Coastguard Worker "certificate": attr.string(mandatory = True), 53*7594170eSAndroid Build Coastguard Worker }, 54*7594170eSAndroid Build Coastguard Worker) 55*7594170eSAndroid Build Coastguard Worker 56*7594170eSAndroid Build Coastguard Workerdef android_app_certificate( 57*7594170eSAndroid Build Coastguard Worker name, 58*7594170eSAndroid Build Coastguard Worker certificate, 59*7594170eSAndroid Build Coastguard Worker **kwargs): 60*7594170eSAndroid Build Coastguard Worker "Bazel macro to correspond with the Android app certificate Soong module." 61*7594170eSAndroid Build Coastguard Worker 62*7594170eSAndroid Build Coastguard Worker _android_app_certificate( 63*7594170eSAndroid Build Coastguard Worker name = name, 64*7594170eSAndroid Build Coastguard Worker pem = certificate + ".x509.pem", 65*7594170eSAndroid Build Coastguard Worker pk8 = certificate + ".pk8", 66*7594170eSAndroid Build Coastguard Worker certificate = certificate, 67*7594170eSAndroid Build Coastguard Worker **kwargs 68*7594170eSAndroid Build Coastguard Worker ) 69*7594170eSAndroid Build Coastguard Worker 70*7594170eSAndroid Build Coastguard Workerdef _search_cert_files(cert_name, cert_filegroup): 71*7594170eSAndroid Build Coastguard Worker pk8 = None 72*7594170eSAndroid Build Coastguard Worker pem = None 73*7594170eSAndroid Build Coastguard Worker files = cert_filegroup[DefaultInfo].files.to_list() 74*7594170eSAndroid Build Coastguard Worker 75*7594170eSAndroid Build Coastguard Worker # For overriding to a specific *file* in a provided directory with cert_name in the actual filename 76*7594170eSAndroid Build Coastguard Worker for f in files: 77*7594170eSAndroid Build Coastguard Worker if f.basename == cert_name + ".pk8": 78*7594170eSAndroid Build Coastguard Worker pk8 = f 79*7594170eSAndroid Build Coastguard Worker elif f.basename == cert_name + ".x509.pem": 80*7594170eSAndroid Build Coastguard Worker pem = f 81*7594170eSAndroid Build Coastguard Worker 82*7594170eSAndroid Build Coastguard Worker if not pk8: 83*7594170eSAndroid Build Coastguard Worker fail("Could not find .pk8 file for the module '%s' in the list: %s" % (cert_name, files)) 84*7594170eSAndroid Build Coastguard Worker if not pem: 85*7594170eSAndroid Build Coastguard Worker fail("Could not find .x509.pem file for the module '%s' in the list: %s" % (cert_name, files)) 86*7594170eSAndroid Build Coastguard Worker 87*7594170eSAndroid Build Coastguard Worker return pk8, pem 88*7594170eSAndroid Build Coastguard Worker 89*7594170eSAndroid Build Coastguard Workerdefault_cert_directory = "build/make/target/product/security" 90*7594170eSAndroid Build Coastguard Worker 91*7594170eSAndroid Build Coastguard Workerdef _android_app_certificate_with_default_cert_impl(ctx): 92*7594170eSAndroid Build Coastguard Worker product_var_cert = ctx.attr._default_app_certificate[BuildSettingInfo].value 93*7594170eSAndroid Build Coastguard Worker 94*7594170eSAndroid Build Coastguard Worker cert_name = ctx.attr.cert_name 95*7594170eSAndroid Build Coastguard Worker 96*7594170eSAndroid Build Coastguard Worker if cert_name and product_var_cert: 97*7594170eSAndroid Build Coastguard Worker cert_dir = paths.dirname(product_var_cert) 98*7594170eSAndroid Build Coastguard Worker elif cert_name: 99*7594170eSAndroid Build Coastguard Worker cert_dir = default_cert_directory 100*7594170eSAndroid Build Coastguard Worker elif product_var_cert: 101*7594170eSAndroid Build Coastguard Worker cert_name = paths.basename(product_var_cert) 102*7594170eSAndroid Build Coastguard Worker cert_dir = paths.dirname(product_var_cert) 103*7594170eSAndroid Build Coastguard Worker else: 104*7594170eSAndroid Build Coastguard Worker cert_name = "testkey" 105*7594170eSAndroid Build Coastguard Worker cert_dir = default_cert_directory 106*7594170eSAndroid Build Coastguard Worker 107*7594170eSAndroid Build Coastguard Worker if cert_dir != default_cert_directory: 108*7594170eSAndroid Build Coastguard Worker filegroup_to_search = ctx.attr._default_app_certificate_filegroup 109*7594170eSAndroid Build Coastguard Worker else: 110*7594170eSAndroid Build Coastguard Worker filegroup_to_search = ctx.attr._hardcoded_certs 111*7594170eSAndroid Build Coastguard Worker 112*7594170eSAndroid Build Coastguard Worker pk8, pem = _search_cert_files(cert_name, filegroup_to_search) 113*7594170eSAndroid Build Coastguard Worker 114*7594170eSAndroid Build Coastguard Worker return [ 115*7594170eSAndroid Build Coastguard Worker AndroidAppCertificateInfo( 116*7594170eSAndroid Build Coastguard Worker pk8 = pk8, 117*7594170eSAndroid Build Coastguard Worker pem = pem, 118*7594170eSAndroid Build Coastguard Worker key_name = "//" + cert_dir + ":" + cert_name, 119*7594170eSAndroid Build Coastguard Worker ), 120*7594170eSAndroid Build Coastguard Worker ] 121*7594170eSAndroid Build Coastguard Worker 122*7594170eSAndroid Build Coastguard Workerandroid_app_certificate_with_default_cert = rule( 123*7594170eSAndroid Build Coastguard Worker doc = """ 124*7594170eSAndroid Build Coastguard Worker This rule is the equivalent of an android_app_certificate, but uses the 125*7594170eSAndroid Build Coastguard Worker certificate with the given name from a certain folder, or the default 126*7594170eSAndroid Build Coastguard Worker certificate. 127*7594170eSAndroid Build Coastguard Worker 128*7594170eSAndroid Build Coastguard Worker Modules can give a simple name of a certificate instead of a full label to 129*7594170eSAndroid Build Coastguard Worker an android_app_certificate. This certificate will be looked for either in 130*7594170eSAndroid Build Coastguard Worker the package determined by the DefaultAppCertificate product config variable, 131*7594170eSAndroid Build Coastguard Worker or the hardcoded default directory. (build/make/target/product/security) 132*7594170eSAndroid Build Coastguard Worker 133*7594170eSAndroid Build Coastguard Worker If a name is not given, it will fall back to using the certificate termined 134*7594170eSAndroid Build Coastguard Worker by DefaultAppCertificate. (DefaultAppCertificate can function as both the 135*7594170eSAndroid Build Coastguard Worker default certificate to use if none is specified, and the folder to look for 136*7594170eSAndroid Build Coastguard Worker certificates in) 137*7594170eSAndroid Build Coastguard Worker 138*7594170eSAndroid Build Coastguard Worker If neither the name nor DefaultAppCertificate is given, 139*7594170eSAndroid Build Coastguard Worker build/make/target/product/security/testkey.{pem,pk8} will be used. 140*7594170eSAndroid Build Coastguard Worker 141*7594170eSAndroid Build Coastguard Worker Since this rule is intended to be used from other macros, it's common to have 142*7594170eSAndroid Build Coastguard Worker multiple android_app_certificate targets pointing to the same pem/pk8 files. 143*7594170eSAndroid Build Coastguard Worker """, 144*7594170eSAndroid Build Coastguard Worker implementation = _android_app_certificate_with_default_cert_impl, 145*7594170eSAndroid Build Coastguard Worker attrs = { 146*7594170eSAndroid Build Coastguard Worker "cert_name": attr.string(), 147*7594170eSAndroid Build Coastguard Worker "_default_app_certificate": attr.label( 148*7594170eSAndroid Build Coastguard Worker default = "//build/bazel/product_config:default_app_certificate", 149*7594170eSAndroid Build Coastguard Worker ), 150*7594170eSAndroid Build Coastguard Worker "_default_app_certificate_filegroup": attr.label( 151*7594170eSAndroid Build Coastguard Worker default = "//build/bazel/product_config:default_app_certificate_filegroup", 152*7594170eSAndroid Build Coastguard Worker ), 153*7594170eSAndroid Build Coastguard Worker "_hardcoded_certs": attr.label( 154*7594170eSAndroid Build Coastguard Worker default = "//build/make/target/product/security:android_certificate_directory", 155*7594170eSAndroid Build Coastguard Worker ), 156*7594170eSAndroid Build Coastguard Worker "_apex_name": attr.label( 157*7594170eSAndroid Build Coastguard Worker default = "//build/bazel/rules/apex:apex_name", 158*7594170eSAndroid Build Coastguard Worker doc = "Name of apex this certificate signs.", 159*7594170eSAndroid Build Coastguard Worker ), 160*7594170eSAndroid Build Coastguard Worker }, 161*7594170eSAndroid Build Coastguard Worker) 162