Skip to content

Commit

Permalink
feat: implement java_keystore
Browse files Browse the repository at this point in the history
  • Loading branch information
thesayyn committed Nov 17, 2023
1 parent 5b47360 commit af39150
Show file tree
Hide file tree
Showing 13 changed files with 562 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .bazelversion
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
6.2.1
6.4.0
# The first line of this file is used by Bazelisk and Bazel to be sure
# the right version of Bazel is used to build and test this repo.
# This also defines which version is used on CI.
Expand Down
1 change: 1 addition & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ use_repo(bazel_lib_toolchains, "bsd_tar_toolchains")
bazel_dep(name = "gazelle", version = "0.34.0", dev_dependency = True, repo_name = "bazel_gazelle")
bazel_dep(name = "bazel_skylib_gazelle_plugin", version = "1.5.0", dev_dependency = True)
bazel_dep(name = "buildifier_prebuilt", version = "6.1.2", dev_dependency = True)
bazel_dep(name = "rules_java", version = "7.3.0", dev_dependency = True)
1 change: 1 addition & 0 deletions distroless/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ bzl_library(
deps = [
"//distroless/private:cacerts",
"//distroless/private:group",
"//distroless/private:java_keystore",
"//distroless/private:locale",
"//distroless/private:os_release",
"//distroless/private:passwd",
Expand Down
2 changes: 2 additions & 0 deletions distroless/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

load("//distroless/private:cacerts.bzl", _cacerts = "cacerts")
load("//distroless/private:group.bzl", _group = "group")
load("//distroless/private:java_keystore.bzl", _java_keystore = "java_keystore")
load("//distroless/private:locale.bzl", _locale = "locale")
load("//distroless/private:os_release.bzl", _os_release = "os_release")
load("//distroless/private:passwd.bzl", _passwd = "passwd")
Expand All @@ -11,3 +12,4 @@ locale = _locale
os_release = _os_release
group = _group
passwd = _passwd
java_keystore = _java_keystore
12 changes: 11 additions & 1 deletion distroless/private/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")

exports_files(["cacerts.sh"])
exports_files([
"cacerts.sh",
"java_keystore.sh",
])

bzl_library(
name = "cacerts",
Expand Down Expand Up @@ -52,6 +55,13 @@ bzl_library(
],
)

bzl_library(
name = "java_keystore",
srcs = ["java_keystore.bzl"],
visibility = ["//distroless:__subpackages__"],
deps = [":tar"],
)

bzl_library(
name = "tar",
srcs = ["tar.bzl"],
Expand Down
76 changes: 76 additions & 0 deletions distroless/private/java_keystore.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"jks"

load(":tar.bzl", "tar_lib")

_DOC = """Create a java keystore (database) of cryptographic keys, X.509 certificate chains, and trusted certificates.
Currently only public X.509 are supported as part of the PUBLIC API contract.
"""

def _find_keytool(java_runtime):
for f in java_runtime.files.to_list():
if f.basename == "keytool":
return f
fail("java toolchain does not contain `keytool`.")

def _java_keystore_impl(ctx):
jdk = ctx.toolchains["@bazel_tools//tools/jdk:runtime_toolchain_type"]
coreutils = ctx.toolchains["@aspect_bazel_lib//lib:coreutils_toolchain_type"]
bsdtar = ctx.toolchains[tar_lib.TOOLCHAIN_TYPE]
keytool = _find_keytool(jdk.java_runtime)

jks = ctx.actions.declare_file(ctx.attr.name + ".jks")

args = ctx.actions.args()

args.add(bsdtar.tarinfo.binary)
args.add(keytool)
args.add(coreutils.coreutils_info.bin)
args.add(jks)
args.add_all(ctx.files.certificates)

ctx.actions.run(
executable = ctx.executable._java_keystore_sh,
tools = depset(
[keytool, coreutils.coreutils_info.bin],
transitive = [bsdtar.default.files],
),
inputs = ctx.files.certificates,
outputs = [jks],
arguments = [args],
)

output = ctx.actions.declare_file(ctx.attr.name + ".tar.gz")
mtree = tar_lib.create_mtree(ctx)
mtree.add_file_with_parents("/etc/ssl/certs/java/cacerts", jks)
mtree.build(output = output, mnemonic = "JavaKeyStore", inputs = [jks])

return [
DefaultInfo(files = depset([output])),
OutputGroupInfo(
jks = depset([jks]),
),
]

java_keystore = rule(
doc = _DOC,
attrs = {
"_java_keystore_sh": attr.label(
allow_single_file = True,
executable = True,
cfg = "exec",
default = ":java_keystore.sh",
),
"certificates": attr.label_list(
allow_files = True,
mandatory = True,
allow_empty = False,
),
},
implementation = _java_keystore_impl,
toolchains = [
tar_lib.TOOLCHAIN_TYPE,
"@bazel_tools//tools/jdk:runtime_toolchain_type",
"@aspect_bazel_lib//lib:coreutils_toolchain_type",
],
)
19 changes: 19 additions & 0 deletions distroless/private/java_keystore.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -o pipefail -o errexit -o nounset

readonly bsdtar="$1"
readonly keytool="$2"
readonly coreutils="$3"
readonly output="$4"
shift 4;

tmp=$(mktemp -d)
while (( $# > 0 )); do
$coreutils csplit --quiet --elide-empty-files -f "$tmp/crt" -b "%02d_$#.crt" -k $1 '/-----BEGIN CERTIFICATE-----/' '{*}'
shift;
done

for f in "$tmp"/*; do
subject=$(openssl x509 -noout -subject -in $f | tr -d " ")
$keytool -importcert -keystore $output -storepass changeit -file $f -alias "${subject#"subject="}" -noprompt
done
25 changes: 25 additions & 0 deletions distroless/tests/asserts.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,28 @@ def assert_tar_listing(name, actual, expected):
file2 = expected_listing,
timeout = "short",
)

# buildifier: disable=function-docstring
def assert_jks_listing(name, actual, expected):
actual_listing = "_{}_listing".format(name)

native.genrule(
name = actual_listing,
srcs = [
actual,
"@rules_java//toolchains:current_java_runtime",
],
outs = ["_{}.listing".format(name)],
cmd = """
BINS=($(locations @rules_java//toolchains:current_java_runtime))
KEYTOOL=$$(dirname $${BINS[1]})/keytool
$$KEYTOOL -list -v -keystore $(location %s) -storepass changeit > $@
""" % actual,
)

diff_test(
name = name,
file1 = actual_listing,
file2 = expected,
timeout = "short",
)
22 changes: 22 additions & 0 deletions docs/rules.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 37 additions & 0 deletions examples/java_keystore/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
load("//distroless:defs.bzl", "java_keystore")
load("//distroless/tests:asserts.bzl", "assert_jks_listing", "assert_tar_listing")

java_keystore(
name = "java_keystore",
certificates = [
# asserting that we support both bundle x509 certs
# and single x509 certs
"amazon.crt",
"bundle.crt",
],
)

filegroup(
name = "java_keystore_jks",
srcs = [":java_keystore"],
output_group = "jks",
)

assert_jks_listing(
name = "test_java_keystore_jks",
actual = "java_keystore_jks",
expected = "expected.jks.output",
)

assert_tar_listing(
name = "test_java_keystore",
actual = "java_keystore",
expected = """\
#mtree
./etc time=1672560000.0 mode=755 gid=0 uid=0 type=dir
./etc/ssl time=1672560000.0 mode=755 gid=0 uid=0 type=dir
./etc/ssl/certs time=1672560000.0 mode=755 gid=0 uid=0 type=dir
./etc/ssl/certs/java time=1672560000.0 mode=755 gid=0 uid=0 type=dir
./etc/ssl/certs/java/cacerts nlink=0 time=1672560000.0 mode=755 gid=0 uid=0 type=file size=6230 cksum=2439835119 sha1digest=525ab823d4735763050000c0d85d00b401f6ce7f
""",
)
20 changes: 20 additions & 0 deletions examples/java_keystore/amazon.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj
ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM
9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw
IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6
VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L
93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm
jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA
A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI
U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs
N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv
o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU
5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy
rqXRfboQnoZsG4q5WTP468SQvvG5
-----END CERTIFICATE-----
93 changes: 93 additions & 0 deletions examples/java_keystore/bundle.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
-----BEGIN CERTIFICATE-----
MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB
vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W
ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX
MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0
IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y
IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh
bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF
9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH
H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H
LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN
/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT
rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud
EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw
WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs
exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4
sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+
seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz
4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+
BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR
lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3
7M2CYfE45k+XmCpajQ==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG
A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8
RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT
gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm
KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd
QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ
XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw
DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o
LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU
RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp
jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX
mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
WD9f
-----END CERTIFICATE-----
Loading

0 comments on commit af39150

Please sign in to comment.