blob: b438c4c693a0768ed1343b03e7f78a32f3e63494 [file] [log] [blame]
# Copyright (C) 2022 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load("@bazel_skylib//lib:paths.bzl", "paths")
load("android_app_certificate.bzl", "AndroidAppCertificateInfo")
AndroidAppKeystoreInfo = provider(
"Info needed for Android app keystores",
fields = {
"keystore": "JKS .keystore file housing certificate info",
},
)
def _pk8_to_private_pem(ctx, openssl, pk8_file, private_pem_file):
"""Converts a .pk8 private key file in DER format to a .pem private key file in PEM format."""
args = ctx.actions.args()
args.add("pkcs8")
args.add_all(["-in", pk8_file])
args.add_all(["-inform", "DER"])
args.add_all(["-outform", "PEM"])
args.add_all(["-out", private_pem_file])
args.add("-nocrypt") # don't bother encrypting this private key since it is just an intermediate file
ctx.actions.run(
inputs = [pk8_file],
executable = openssl,
outputs = [private_pem_file],
arguments = [args],
mnemonic = "CreatePrivPEM",
)
def _pem_to_pk12(ctx, openssl, certificate_pem, private_key_pem, pk12_file):
"""Converts an X.509 certificate and private key pair of PEM files to a single PKCS12 keystore file."""
args = ctx.actions.args()
args.add("pkcs12")
args.add("-export")
args.add_all(["-in", certificate_pem])
args.add_all(["-inkey", private_key_pem])
args.add_all(["-out", pk12_file])
args.add_all(["-name", "android"])
# openssl requires a password and will request a
# password from STDIN if we don't supply one here
args.add_all(["-passout", "pass:android"])
ctx.actions.run(
inputs = [
certificate_pem,
private_key_pem,
],
executable = openssl,
outputs = [pk12_file],
arguments = [args],
mnemonic = "CreatePK12",
)
def _pk12_to_keystore(ctx, pk12_file, keystore_file):
"""Converts a PKCS12 keystore file to a JKS keystore file."""
java_runtime = ctx.attr._java_runtime[java_common.JavaRuntimeInfo]
keytool = paths.join(java_runtime.java_home, "bin", "keytool")
args = ctx.actions.args()
args.add("-importkeystore")
args.add_all(["-destkeystore", keystore_file])
args.add_all(["-srckeystore", pk12_file])
args.add_all(["-srcstoretype", "PKCS12"])
args.add_all(["-srcstorepass", "android"])
# apksigner expects keystores provided by the debug_signing_keys attribute
# to be secured with the password "android"
args.add_all(["-deststorepass", "android"])
ctx.actions.run(
inputs = [pk12_file],
executable = keytool,
tools = [java_runtime.files],
outputs = [keystore_file],
arguments = [args],
mnemonic = "CreateKeystore",
)
def _android_app_keystore_rule_impl(ctx):
openssl = ctx.executable._openssl
private_pem = ctx.actions.declare_file(ctx.attr.name + ".priv.pem")
pk12 = ctx.actions.declare_file(ctx.attr.name + ".pk12")
keystore = ctx.actions.declare_file(ctx.attr.name + ".keystore")
pk8_file = ctx.attr.certificate[AndroidAppCertificateInfo].pk8
pem_file = ctx.attr.certificate[AndroidAppCertificateInfo].pem
_pk8_to_private_pem(ctx, openssl, pk8_file, private_pem)
_pem_to_pk12(ctx, openssl, pem_file, private_pem, pk12)
_pk12_to_keystore(ctx, pk12, keystore)
return [
AndroidAppKeystoreInfo(
keystore = keystore,
),
DefaultInfo(files = depset(direct = [keystore])),
]
"""Converts an android_app_certificate (i.e. pem/pk8 pair) into a JKS keystore"""
android_app_keystore = rule(
implementation = _android_app_keystore_rule_impl,
attrs = {
"certificate": attr.label(mandatory = True, providers = [AndroidAppCertificateInfo]),
"_openssl": attr.label(
default = Label("//prebuilts/build-tools:linux-x86/bin/openssl"),
allow_single_file = True,
executable = True,
cfg = "exec",
doc = "An OpenSSL compatible tool.",
),
"_java_runtime": attr.label(
default = Label("@bazel_tools//tools/jdk:current_java_runtime"),
cfg = "exec",
providers = [java_common.JavaRuntimeInfo],
),
},
provides = [AndroidAppKeystoreInfo],
)