Created
October 9, 2025 02:58
-
-
Save sireza/eb2d2e166c510a333893a962681e9cd2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Script to fetch SSL certificate chain from a URL and create a PKCS12 keystore | |
# Usage: ./ssl-cert-to-keystore.sh <URL> | |
set -e # Exit on any error | |
# Function to display usage | |
usage() { | |
echo "Usage: $0 <URL>" | |
echo "Example: $0 google.com" | |
echo " $0 https://example.com" | |
exit 1 | |
} | |
# Function to check if Java is installed | |
check_java() { | |
echo "Checking Java Runtime Environment..." | |
# Check if java command is available | |
if ! command -v java >/dev/null 2>&1; then | |
echo "Error: Java Runtime Environment (JRE/JDK) is not installed or not in PATH" | |
echo "keytool requires Java Runtime Environment to function" | |
echo "" | |
echo "Please install one of the following:" | |
echo " - Java JDK (includes JRE + development tools)" | |
echo " - Java JRE (runtime only, sufficient for keytool)" | |
echo "" | |
echo "Download options:" | |
echo " - OpenJDK: https://adoptium.net/" | |
echo " - Oracle Java: https://www.oracle.com/java/" | |
echo " - Amazon Corretto: https://aws.amazon.com/corretto/" | |
exit 1 | |
fi | |
# Test Java runtime functionality | |
if ! java -version >/dev/null 2>&1; then | |
echo "Error: Java runtime is not functioning properly" | |
echo "Please reinstall Java Runtime Environment (JRE/JDK)" | |
exit 1 | |
fi | |
# Get and display Java version information | |
JAVA_VERSION=$(java -version 2>&1 | head -n 1) | |
JAVA_RUNTIME_INFO=$(java -version 2>&1 | grep -i "runtime\|vm\|jre\|jdk" | head -n 1 || echo "") | |
echo "✓ Java Runtime found: $JAVA_VERSION" | |
if [ -n "$JAVA_RUNTIME_INFO" ]; then | |
echo " Runtime info: $JAVA_RUNTIME_INFO" | |
fi | |
# Check if keytool is available | |
if ! command -v keytool >/dev/null 2>&1; then | |
echo "Warning: keytool command not found in PATH" | |
echo "Attempting to locate keytool in common Java installation directories..." | |
# Common keytool locations | |
KEYTOOL_LOCATIONS=( | |
"$JAVA_HOME/bin/keytool" | |
"/usr/bin/keytool" | |
"/usr/local/bin/keytool" | |
"$(dirname "$(command -v java)")/keytool" | |
) | |
KEYTOOL_FOUND=false | |
for location in "${KEYTOOL_LOCATIONS[@]}"; do | |
if [ -f "$location" ] && [ -x "$location" ]; then | |
echo "✓ Found keytool at: $location" | |
# Update PATH to include keytool location if needed | |
KEYTOOL_DIR=$(dirname "$location") | |
if [[ ":$PATH:" != *":$KEYTOOL_DIR:"* ]]; then | |
export PATH="$KEYTOOL_DIR:$PATH" | |
echo " Added to PATH: $KEYTOOL_DIR" | |
fi | |
KEYTOOL_FOUND=true | |
break | |
fi | |
done | |
if [ "$KEYTOOL_FOUND" = false ]; then | |
echo "Error: keytool not found" | |
echo "keytool is required and should be included with Java installations" | |
echo "" | |
echo "Solutions:" | |
echo " 1. Install Java JDK (includes keytool)" | |
echo " 2. Ensure keytool is in your PATH" | |
echo " 3. Set JAVA_HOME environment variable" | |
exit 1 | |
fi | |
else | |
echo "✓ keytool found: $(command -v keytool)" | |
fi | |
# Test keytool functionality | |
if ! keytool -help >/dev/null 2>&1; then | |
echo "Error: keytool is not functioning properly" | |
echo "Please check your Java installation" | |
exit 1 | |
fi | |
# Check JAVA_HOME (recommended for consistency) | |
if [ -z "$JAVA_HOME" ]; then | |
echo "Info: JAVA_HOME is not set (recommended but not required)" | |
JAVA_PATH=$(command -v java) | |
POSSIBLE_JAVA_HOME=$(dirname "$(dirname "$JAVA_PATH")") | |
echo " Suggested JAVA_HOME: $POSSIBLE_JAVA_HOME" | |
else | |
echo "✓ JAVA_HOME: $JAVA_HOME" | |
fi | |
echo "✓ Java Runtime Environment validation passed" | |
echo | |
} | |
# Function to extract hostname and port from URL | |
parse_url() { | |
local url="$1" | |
# Remove protocol if present | |
url=$(echo "$url" | sed -e 's|^https://||' -e 's|^http://||' -e 's|^ssl://||') | |
# Extract hostname and port | |
if [[ "$url" == *":"* ]]; then | |
hostname=$(echo "$url" | cut -d':' -f1) | |
port=$(echo "$url" | cut -d':' -f2 | cut -d'/' -f1) | |
else | |
hostname=$(echo "$url" | cut -d'/' -f1) | |
port=443 | |
fi | |
echo "$hostname:$port" | |
} | |
# Check if URL parameter is provided | |
if [ $# -eq 0 ]; then | |
echo "Error: URL parameter is required" | |
usage | |
fi | |
# Validate Java installation | |
check_java | |
URL="$1" | |
PARSED_URL=$(parse_url "$URL") | |
HOSTNAME=$(echo "$PARSED_URL" | cut -d':' -f1) | |
PORT=$(echo "$PARSED_URL" | cut -d':' -f2) | |
echo "Fetching SSL certificate chain from: $HOSTNAME:$PORT" | |
# Create temporary directory for certificates | |
TEMP_DIR=$(mktemp -d) | |
CERT_CHAIN_FILE="$TEMP_DIR/cert_chain.pem" | |
CERT_PEM_FILE="$TEMP_DIR/certificate.pem" | |
OUTPUT_P12_FILE="${HOSTNAME}_keystore.p12" | |
# Cleanup function | |
cleanup() { | |
rm -rf "$TEMP_DIR" | |
} | |
trap cleanup EXIT | |
echo "Retrieving certificate chain..." | |
# Get the certificate chain using openssl | |
if ! openssl s_client -connect "$HOSTNAME:$PORT" -servername "$HOSTNAME" -showcerts </dev/null 2>/dev/null | sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' > "$CERT_CHAIN_FILE"; then | |
echo "Error: Failed to retrieve certificate chain from $HOSTNAME:$PORT" | |
echo "Please check if the hostname and port are correct and accessible." | |
exit 1 | |
fi | |
# Check if we got any certificates | |
if [ ! -s "$CERT_CHAIN_FILE" ]; then | |
echo "Error: No certificates found for $HOSTNAME:$PORT" | |
echo "Please verify the hostname and port are correct." | |
exit 1 | |
fi | |
# Count the number of certificates in the chain | |
CERT_COUNT=$(grep -c -- "-----BEGIN CERTIFICATE-----" "$CERT_CHAIN_FILE" || echo "0") | |
echo "Found $CERT_COUNT certificate(s) in the chain" | |
# Extract just the server certificate (first one) for the keystore | |
sed -n '1,/-----END CERTIFICATE-----/p' "$CERT_CHAIN_FILE" > "$CERT_PEM_FILE" | |
echo "Certificate chain saved to temporary file: $CERT_CHAIN_FILE" | |
echo "Server certificate extracted to: $CERT_PEM_FILE" | |
# Display certificate information | |
echo | |
echo "Certificate Information:" | |
echo "========================" | |
openssl x509 -in "$CERT_PEM_FILE" -text -noout | grep -E "(Subject:|Issuer:|Not Before:|Not After:)" || echo "Could not extract certificate information" | |
echo | |
echo "Creating PKCS12 keystore..." | |
echo "You will be prompted to enter a password for the keystore." | |
echo "Note: Since we only have the public certificate (not the private key)," | |
echo "this keystore will contain the certificate for trust purposes only." | |
# Create PKCS12 keystore using keytool | |
# Note: We're creating a truststore since we don't have the private key | |
if keytool -importcert -file "$CERT_PEM_FILE" -alias "$HOSTNAME" -keystore "$OUTPUT_P12_FILE" -storetype PKCS12; then | |
echo | |
echo "SUCCESS: PKCS12 keystore created successfully!" | |
echo "Output file: $OUTPUT_P12_FILE" | |
echo | |
echo "You can view the keystore contents with:" | |
echo "keytool -list -keystore $OUTPUT_P12_FILE -storetype PKCS12" | |
else | |
echo "Error: Failed to create PKCS12 keystore" | |
exit 1 | |
fi | |
echo | |
echo "Full certificate chain has been saved and processed." | |
echo "The keystore '$OUTPUT_P12_FILE' contains the server certificate for $HOSTNAME." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment