xref: /aosp_15_r20/build/bazel/rules/android/android_app_certificate.bzl (revision 7594170e27e0732bc44b93d1440d87a54b6ffe7c)
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