Files
blog_data/scripts/Base/empty_trustsore.sh
T

155 lines
5.3 KiB
Bash

#!/bin/bash
# Usage:
# ./create-truststore.sh [CA_CERT [TRUSTSTORE [ALIAS]]]
# ./create-truststore.sh --verify [CA_CERT [TRUSTSTORE [ALIAS]]]
# Defaults may be overridden with CERT_DIR, CA_CERT, TRUSTSTORE, CA_ALIAS, JAVA_BIN.
# Requires Java 8+; javac is required on Java 8-10.
# Java 11+ supports source-file mode when the jdk.compiler module is available.
set -euo pipefail
CERT_DIR="${CERT_DIR:-/site/var/spring/key}"
CA_CERT="${CA_CERT:-${CERT_DIR}/local-root-ca.crt}"
TRUSTSTORE="${TRUSTSTORE:-${CERT_DIR}/truststore-empty.jks}"
CA_ALIAS="${CA_ALIAS:-local-root-ca}"
MODE=create
if [[ "${1:-}" == --verify ]]; then
MODE=verify
shift
fi
CA_CERT="${1:-${CA_CERT}}"
TRUSTSTORE="${2:-${TRUSTSTORE}}"
CA_ALIAS="${3:-${CA_ALIAS}}"
if (( $# > 3 )); then
echo 'Usage: create-truststore.sh [--verify] [CA_CERT [TRUSTSTORE [ALIAS]]]' >&2
exit 2
fi
if [[ ! -r "${CA_CERT}" ]]; then
echo "ERROR: CA certificate not readable: ${CA_CERT}" >&2
exit 1
fi
if [[ "${MODE}" == create && -e "${TRUSTSTORE}" ]]; then
echo "ERROR: TrustStore already exists: ${TRUSTSTORE}" >&2
exit 1
fi
if [[ "${MODE}" == verify && ! -r "${TRUSTSTORE}" ]]; then
echo "ERROR: TrustStore not readable: ${TRUSTSTORE}" >&2
exit 1
fi
JAVA_BIN="${JAVA_BIN:-$(which java 2>/dev/null || true)}"
if [[ -z "${JAVA_BIN}" || ! -x "${JAVA_BIN}" ]]; then
echo 'ERROR: java not found (set JAVA_BIN or add java to PATH)' >&2
exit 1
fi
JAVA_MAJOR="$("${JAVA_BIN}" -version 2>&1 | awk -F '"' '/version/ {split($2, v, "."); print (v[1] == "1" ? v[2] : v[1]); exit}')"
if [[ ! "${JAVA_MAJOR}" =~ ^[0-9]+$ || "${JAVA_MAJOR}" -lt 8 ]]; then
echo 'ERROR: cannot determine Java version or Java is older than 8' >&2
exit 1
fi
WORK_DIR="$(mktemp -d)"
trap 'rm -rf -- "${WORK_DIR}"' EXIT
SOURCE="${WORK_DIR}/CreateTrustStore.java"
cat > "${SOURCE}" <<'JAVA'
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
public class CreateTrustStore {
public static void main(String[] args) throws Exception {
String mode = args[0];
String certPath = args[1];
String storePath = args[2];
String alias = args[3];
char[] password = new char[0];
Certificate ca;
try (InputStream in = Files.newInputStream(Paths.get(certPath))) {
ca = CertificateFactory.getInstance("X.509").generateCertificate(in);
}
KeyStore store = KeyStore.getInstance("JKS");
if ("create".equals(mode)) {
store.load(null, password);
store.setCertificateEntry(alias, ca);
try (OutputStream out = Files.newOutputStream(
Paths.get(storePath), StandardOpenOption.CREATE_NEW)) {
store.store(out, password);
}
} else if (!"verify".equals(mode)) {
throw new IllegalArgumentException("Unknown mode: " + mode);
}
try (InputStream in = Files.newInputStream(Paths.get(storePath))) {
store.load(in, password);
}
if (!store.isCertificateEntry(alias) || !ca.equals(store.getCertificate(alias))) {
throw new IllegalStateException("CA certificate/alias mismatch");
}
System.out.println("OK: JKS verified with empty password; alias=" + alias);
}
}
JAVA
umask 077
# Prefer javac from the selected Java installation to avoid mixing JDK versions.
# For Java 11+ source-file mode is preferred, especially on JRE-only systems.
resolve_javac() {
local java_real java_dir candidate
java_real="$(readlink -f -- "${JAVA_BIN}" 2>/dev/null || printf '%s' "${JAVA_BIN}")"
java_dir="$(dirname -- "${java_real}")"
candidate="${JAVAC_BIN:-${java_dir}/javac}"
if [[ -x "${candidate}" ]]; then
printf '%s\n' "${candidate}"
return 0
fi
# A java executable in PATH may be a wrapper; javac from PATH is usable
# only when it belongs to the same major Java version.
if [[ -z "${JAVAC_BIN:-}" ]]; then
candidate="$(which javac 2>/dev/null || true)"
if [[ -n "${candidate}" && -x "${candidate}" ]]; then
local compiler_major
compiler_major="$("${candidate}" -version 2>&1 | awk '{split($2,v,"."); print (v[1] == "1" ? v[2] : v[1])}')"
if [[ "${compiler_major}" == "${JAVA_MAJOR}" ]]; then
printf '%s\n' "${candidate}"
return 0
fi
fi
fi
return 1
}
run_compiled() {
local compiler
compiler="$(resolve_javac)" || {
echo "ERROR: Java ${JAVA_MAJOR}: javac from the matching JDK is required" >&2
return 1
}
"${compiler}" -d "${WORK_DIR}" "${SOURCE}"
"${JAVA_BIN}" -cp "${WORK_DIR}" CreateTrustStore "${MODE}" "${CA_CERT}" "${TRUSTSTORE}" "${CA_ALIAS}"
}
if (( JAVA_MAJOR >= 11 )); then
# A runtime image can omit jdk.compiler: fall back to javac if available.
if "${JAVA_BIN}" --list-modules 2>/dev/null | grep -q '^jdk.compiler@'; then
"${JAVA_BIN}" "${SOURCE}" "${MODE}" "${CA_CERT}" "${TRUSTSTORE}" "${CA_ALIAS}"
else
run_compiled
fi
else
run_compiled
fi
if [[ "${MODE}" == create ]]; then
chmod 640 -- "${TRUSTSTORE}"
echo "TrustStore created: ${TRUSTSTORE}"
fi