diff --git a/.bazelversion b/.bazelversion index 252d869..b4258ec 100644 --- a/.bazelversion +++ b/.bazelversion @@ -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. diff --git a/MODULE.bazel b/MODULE.bazel index 711569b..426e5d2 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -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) diff --git a/distroless/BUILD.bazel b/distroless/BUILD.bazel index 06ac0e8..9fa2563 100644 --- a/distroless/BUILD.bazel +++ b/distroless/BUILD.bazel @@ -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", diff --git a/distroless/defs.bzl b/distroless/defs.bzl index c534e1a..face129 100644 --- a/distroless/defs.bzl +++ b/distroless/defs.bzl @@ -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") @@ -11,3 +12,4 @@ locale = _locale os_release = _os_release group = _group passwd = _passwd +java_keystore = _java_keystore diff --git a/distroless/private/BUILD.bazel b/distroless/private/BUILD.bazel index d254cbf..bbecf58 100644 --- a/distroless/private/BUILD.bazel +++ b/distroless/private/BUILD.bazel @@ -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", @@ -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"], diff --git a/distroless/private/java_keystore.bzl b/distroless/private/java_keystore.bzl new file mode 100644 index 0000000..9f91563 --- /dev/null +++ b/distroless/private/java_keystore.bzl @@ -0,0 +1,73 @@ +"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"] + 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(jks) + args.add_all(ctx.files.certificates) + + ctx.actions.run( + executable = ctx.executable._java_keystore_sh, + tools = depset( + [keytool], + 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", + ], +) diff --git a/distroless/private/java_keystore.sh b/distroless/private/java_keystore.sh new file mode 100755 index 0000000..9af2020 --- /dev/null +++ b/distroless/private/java_keystore.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -o pipefail -o errexit -o nounset + +readonly bsdtar="$1" +readonly keytool="$2" +readonly output="$3" +shift 3; + +tmp=$(mktemp -d) +while (( $# > 0 )); do + split -p "-----BEGIN CERTIFICATE-----" $1 "$tmp/cert-$#" + 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 \ No newline at end of file diff --git a/distroless/tests/asserts.bzl b/distroless/tests/asserts.bzl index c67139b..23259d3 100644 --- a/distroless/tests/asserts.bzl +++ b/distroless/tests/asserts.bzl @@ -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", + ) diff --git a/docs/rules.md b/docs/rules.md index d565189..851cdab 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -50,6 +50,28 @@ cacerts( | package | - | Label | required | | + + +## java_keystore + +
+java_keystore(name, certificates)
+
+ +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. + + +**ATTRIBUTES** + + +| Name | Description | Type | Mandatory | Default | +| :------------- | :------------- | :------------- | :------------- | :------------- | +| name | A unique name for this target. | Name | required | | +| certificates | - | List of labels | required | | + + ## locale diff --git a/examples/java_keystore/BUILD.bazel b/examples/java_keystore/BUILD.bazel new file mode 100644 index 0000000..8c50bee --- /dev/null +++ b/examples/java_keystore/BUILD.bazel @@ -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=80474609 sha1digest=83cf565e39cd1ccd26cb45d66053cf77e86dcedd +""", +) diff --git a/examples/java_keystore/amazon.crt b/examples/java_keystore/amazon.crt new file mode 100644 index 0000000..61ae256 --- /dev/null +++ b/examples/java_keystore/amazon.crt @@ -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----- \ No newline at end of file diff --git a/examples/java_keystore/bundle.crt b/examples/java_keystore/bundle.crt new file mode 100644 index 0000000..8bdace1 --- /dev/null +++ b/examples/java_keystore/bundle.crt @@ -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----- \ No newline at end of file diff --git a/examples/java_keystore/expected.jks.output b/examples/java_keystore/expected.jks.output new file mode 100644 index 0000000..8e68cb2 --- /dev/null +++ b/examples/java_keystore/expected.jks.output @@ -0,0 +1,254 @@ +Keystore type: PKCS12 +Keystore provider: SUN + +Your keystore contains 5 entries + +Alias name: /c=us/o=amazon/cn=amazonrootca1 +Creation date: Nov. 17, 2023 +Entry type: trustedCertEntry + +Owner: CN=Amazon Root CA 1, O=Amazon, C=US +Issuer: CN=Amazon Root CA 1, O=Amazon, C=US +Serial number: 66c9fcf99bf8c0a39e2f0788a43e696365bca +Valid from: Mon May 25 17:00:00 PDT 2015 until: Sat Jan 16 16:00:00 PST 2038 +Certificate fingerprints: + SHA1: 8D:A7:F9:65:EC:5E:FC:37:91:0F:1C:6E:59:FD:C1:CC:6A:6E:DE:16 + SHA256: 8E:CD:E6:88:4F:3D:87:B1:12:5B:A3:1A:C3:FC:B1:3D:70:16:DE:7F:57:CC:90:4F:E1:CB:97:C6:AE:98:19:6E +Signature algorithm name: SHA256withRSA +Subject Public Key Algorithm: 2048-bit RSA key +Version: 3 + +Extensions: + +#1: ObjectId: 2.5.29.19 Criticality=true +BasicConstraints:[ + CA:true + PathLen: no limit +] + +#2: ObjectId: 2.5.29.15 Criticality=true +KeyUsage [ + DigitalSignature + Key_CertSign + Crl_Sign +] + +#3: ObjectId: 2.5.29.14 Criticality=false +SubjectKeyIdentifier [ +KeyIdentifier [ +0000: 84 18 CC 85 34 EC BC 0C 94 94 2E 08 59 9C C7 B2 ....4.......Y... +0010: 10 4E 0A 08 .N.. +] +] + + + +******************************************* +******************************************* + + +Alias name: /c=us/o=digicertinc/ou=www.digicert.com/cn=digicertassuredidrootca +Creation date: Nov. 17, 2023 +Entry type: trustedCertEntry + +Owner: CN=DigiCert Assured ID Root CA, OU=www.digicert.com, O=DigiCert Inc, C=US +Issuer: CN=DigiCert Assured ID Root CA, OU=www.digicert.com, O=DigiCert Inc, C=US +Serial number: ce7e0e517d846fe8fe560fc1bf03039 +Valid from: Thu Nov 09 16:00:00 PST 2006 until: Sun Nov 09 16:00:00 PST 2031 +Certificate fingerprints: + SHA1: 05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43 + SHA256: 3E:90:99:B5:01:5E:8F:48:6C:00:BC:EA:9D:11:1E:E7:21:FA:BA:35:5A:89:BC:F1:DF:69:56:1E:3D:C6:32:5C +Signature algorithm name: SHA1withRSA +Subject Public Key Algorithm: 2048-bit RSA key +Version: 3 + +Extensions: + +#1: ObjectId: 2.5.29.35 Criticality=false +AuthorityKeyIdentifier [ +KeyIdentifier [ +0000: 45 EB A2 AF F4 92 CB 82 31 2D 51 8B A7 A7 21 9D E.......1-Q...!. +0010: F3 6D C8 0F .m.. +] +] + +#2: ObjectId: 2.5.29.19 Criticality=true +BasicConstraints:[ + CA:true + PathLen: no limit +] + +#3: ObjectId: 2.5.29.15 Criticality=true +KeyUsage [ + DigitalSignature + Key_CertSign + Crl_Sign +] + +#4: ObjectId: 2.5.29.14 Criticality=false +SubjectKeyIdentifier [ +KeyIdentifier [ +0000: 45 EB A2 AF F4 92 CB 82 31 2D 51 8B A7 A7 21 9D E.......1-Q...!. +0010: F3 6D C8 0F .m.. +] +] + + + +******************************************* +******************************************* + + +Alias name: /c=us/o=verisign,inc./ou=verisigntrustnetwork/ou=(c)2008verisign,inc.-forauthorizeduseonly/cn=verisignuniversalrootcertificationauthority +Creation date: Nov. 17, 2023 +Entry type: trustedCertEntry + +Owner: CN=VeriSign Universal Root Certification Authority, OU="(c) 2008 VeriSign, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US +Issuer: CN=VeriSign Universal Root Certification Authority, OU="(c) 2008 VeriSign, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US +Serial number: 401ac46421b31321030ebbe4121ac51d +Valid from: Tue Apr 01 17:00:00 PDT 2008 until: Tue Dec 01 15:59:59 PST 2037 +Certificate fingerprints: + SHA1: 36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54 + SHA256: 23:99:56:11:27:A5:71:25:DE:8C:EF:EA:61:0D:DF:2F:A0:78:B5:C8:06:7F:4E:82:82:90:BF:B8:60:E8:4B:3C +Signature algorithm name: SHA256withRSA +Subject Public Key Algorithm: 2048-bit RSA key +Version: 3 + +Extensions: + +#1: ObjectId: 1.3.6.1.5.5.7.1.12 Criticality=false +0000: 30 5F A1 5D A0 5B 30 59 30 57 30 55 16 09 69 6D 0_.].[0Y0W0U..im +0010: 61 67 65 2F 67 69 66 30 21 30 1F 30 07 06 05 2B age/gif0!0.0...+ +0020: 0E 03 02 1A 04 14 8F E5 D3 1A 86 AC 8D 8E 6B C3 ..............k. +0030: CF 80 6A D4 48 18 2C 7B 19 2E 30 25 16 23 68 74 ..j.H.,...0%.#ht +0040: 74 70 3A 2F 2F 6C 6F 67 6F 2E 76 65 72 69 73 69 tp://logo.verisi +0050: 67 6E 2E 63 6F 6D 2F 76 73 6C 6F 67 6F 2E 67 69 gn.com/vslogo.gi +0060: 66 f + + +#2: ObjectId: 2.5.29.19 Criticality=true +BasicConstraints:[ + CA:true + PathLen: no limit +] + +#3: ObjectId: 2.5.29.15 Criticality=true +KeyUsage [ + Key_CertSign + Crl_Sign +] + +#4: ObjectId: 2.5.29.14 Criticality=false +SubjectKeyIdentifier [ +KeyIdentifier [ +0000: B6 77 FA 69 48 47 9F 53 12 D5 C2 EA 07 32 76 07 .w.iHG.S.....2v. +0010: D1 97 07 19 .... +] +] + + + +******************************************* +******************************************* + + +Alias name: /ou=globalsignrootca-r2/o=globalsign/cn=globalsign +Creation date: Nov. 17, 2023 +Entry type: trustedCertEntry + +Owner: CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R2 +Issuer: CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R2 +Serial number: 400000000010f8626e60d +Valid from: Fri Dec 15 00:00:00 PST 2006 until: Wed Dec 15 00:00:00 PST 2021 +Certificate fingerprints: + SHA1: 75:E0:AB:B6:13:85:12:27:1C:04:F8:5F:DD:DE:38:E4:B7:24:2E:FE + SHA256: CA:42:DD:41:74:5F:D0:B8:1E:B9:02:36:2C:F9:D8:BF:71:9D:A1:BD:1B:1E:FC:94:6F:5B:4C:99:F4:2C:1B:9E +Signature algorithm name: SHA1withRSA +Subject Public Key Algorithm: 2048-bit RSA key +Version: 3 + +Extensions: + +#1: ObjectId: 2.5.29.35 Criticality=false +AuthorityKeyIdentifier [ +KeyIdentifier [ +0000: 9B E2 07 57 67 1C 1E C0 6A 06 DE 59 B4 9A 2D DF ...Wg...j..Y..-. +0010: DC 19 86 2E .... +] +] + +#2: ObjectId: 2.5.29.19 Criticality=true +BasicConstraints:[ + CA:true + PathLen: no limit +] + +#3: ObjectId: 2.5.29.31 Criticality=false +CRLDistributionPoints [ + [DistributionPoint: + [URIName: http://crl.globalsign.net/root-r2.crl] +]] + +#4: ObjectId: 2.5.29.15 Criticality=true +KeyUsage [ + Key_CertSign + Crl_Sign +] + +#5: ObjectId: 2.5.29.14 Criticality=false +SubjectKeyIdentifier [ +KeyIdentifier [ +0000: 9B E2 07 57 67 1C 1E C0 6A 06 DE 59 B4 9A 2D DF ...Wg...j..Y..-. +0010: DC 19 86 2E .... +] +] + + + +******************************************* +******************************************* + + +Alias name: /ou=globalsignrootca-r3/o=globalsign/cn=globalsign +Creation date: Nov. 17, 2023 +Entry type: trustedCertEntry + +Owner: CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R3 +Issuer: CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R3 +Serial number: 4000000000121585308a2 +Valid from: Wed Mar 18 03:00:00 PDT 2009 until: Sun Mar 18 03:00:00 PDT 2029 +Certificate fingerprints: + SHA1: D6:9B:56:11:48:F0:1C:77:C5:45:78:C1:09:26:DF:5B:85:69:76:AD + SHA256: CB:B5:22:D7:B7:F1:27:AD:6A:01:13:86:5B:DF:1C:D4:10:2E:7D:07:59:AF:63:5A:7C:F4:72:0D:C9:63:C5:3B +Signature algorithm name: SHA256withRSA +Subject Public Key Algorithm: 2048-bit RSA key +Version: 3 + +Extensions: + +#1: ObjectId: 2.5.29.19 Criticality=true +BasicConstraints:[ + CA:true + PathLen: no limit +] + +#2: ObjectId: 2.5.29.15 Criticality=true +KeyUsage [ + Key_CertSign + Crl_Sign +] + +#3: ObjectId: 2.5.29.14 Criticality=false +SubjectKeyIdentifier [ +KeyIdentifier [ +0000: 8F F0 4B 7F A8 2E 45 24 AE 4D 50 FA 63 9A 8B DE ..K...E$.MP.c... +0010: E2 DD 1B BC .... +] +] + + + +******************************************* +******************************************* + +