Last active
August 5, 2024 17:49
-
-
Save bdparrish/9d1efe0c87f8dafb85f8d01996eef069 to your computer and use it in GitHub Desktop.
CLI for generating self signed certificates - server and client
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 | |
# Define color codes | |
RED='\033[0;31m' | |
GREEN='\033[0;32m' | |
YELLOW='\033[0;33m' | |
BLUE='\033[0;34m' | |
MAGENTA='\033[0;35m' | |
CYAN='\033[0;36m' | |
NC='\033[0m' # No Color | |
# Function to create CA Certificate | |
create_ca_certificate() { | |
printf "${GREEN}Creating CA Certificate...${NC}\n" | |
# Generate a private key for the CA | |
openssl genpkey -algorithm RSA -out ca.key -pkeyopt rsa_keygen_bits:2048 | |
if [ $? -ne 0 ]; then | |
printf "${RED}Failed to generate CA private key.${NC}\n" | |
return 1 | |
fi | |
# Generate a self-signed CA certificate | |
openssl req -new -x509 -key ca.key -out ca.crt -days 365 -subj "/C=US/ST=District of Columbia/L=Washington/O=Virtru/OU=Federal/CN=Virtru Federal" | |
if [ $? -ne 0 ]; then | |
printf "${RED}Failed to generate CA certificate.${NC}\n" | |
return 1 | |
fi | |
# Create a truststore and add the CA certificate to it | |
keytool -importcert -file ca.crt -alias ca -keystore truststore.jks -storepass changeit -noprompt | |
if [ $? -ne 0 ]; then | |
printf "${RED}Failed to create truststore or import CA certificate.${NC}\n" | |
return 1 | |
fi | |
printf "${GREEN}CA Certificate and truststore created successfully.${NC}\n" | |
} | |
# Function to create Server Certificate | |
create_server_certificate() { | |
printf "${GREEN}Creating Server Certificate...${NC}\n" | |
# Check if server.crt already exists | |
if [ -f "server.crt" ]; then | |
read -p "server.crt already exists. Do you want to recreate it? (y/n): " choice | |
if [ "$choice" != "y" ]; then | |
printf "${YELLOW}Server certificate creation aborted.${NC}\n" | |
return | |
fi | |
fi | |
# Prompt for the Common Name (CN) value | |
read -p "Enter the Common Name (CN) for the server certificate: " server_cn | |
# Generate a private key for the server | |
openssl genpkey -algorithm RSA -out server.key -pkeyopt rsa_keygen_bits:2048 | |
if [ $? -ne 0 ]; then | |
printf "${RED}Failed to generate server private key.${NC}\n" | |
return 1 | |
fi | |
# Generate a certificate signing request (CSR) for the server | |
openssl req -new -key server.key -out server.csr -subj "/C=US/ST=District of Columbia/L=Washington/O=Virtru/OU=Federal/CN=${server_cn}" | |
if [ $? -ne 0 ]; then | |
printf "${RED}Failed to generate server CSR.${NC}\n" | |
return 1 | |
fi | |
# Create the server.ext file with the DNS alt name | |
cat > server.ext << EOF | |
authorityKeyIdentifier=keyid,issuer | |
basicConstraints=CA:FALSE | |
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment | |
subjectAltName = @alt_names | |
[alt_names] | |
DNS.1 = ${server_cn} | |
EOF | |
# Sign the server CSR with the CA certificate to create the server certificate | |
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -extfile server.ext | |
if [ $? -ne 0 ]; then | |
printf "${RED}Failed to generate server certificate.${NC}\n" | |
return 1 | |
fi | |
# Output PEM files for the server certificate and key | |
openssl x509 -in server.crt -out server-crt.pem -outform PEM | |
openssl rsa -in server.key -out server-key.pem | |
printf "${GREEN}Server certificate and PEM files created successfully.${NC}\n" | |
} | |
# Function to create Client Certificate | |
create_client_certificate() { | |
printf "${GREEN}Creating Client Certificate...${NC}\n" | |
# Prompt for the Common Name (CN) value | |
read -p "Enter the Common Name (CN) for the client certificate: " client_cn | |
# Prompt for the subject's email address | |
read -p "Enter the email address for the client certificate: " client_email | |
# Generate a sanitized filename from the CN value | |
client_filename=$(echo "${client_cn}" | tr '[:upper:]' '[:lower:]' | tr ' ' '_') | |
# Check if the client certificate file already exists | |
if [ -f "${client_filename}.crt" ]; then | |
read -p "${client_filename}.crt already exists. Do you want to replace it? (y/n): " choice | |
if [ "$choice" != "y" ]; then | |
printf "${YELLOW}Client certificate creation aborted.${NC}\n" | |
return | |
fi | |
fi | |
# Generate a private key for the client | |
openssl genpkey -algorithm RSA -out "${client_filename}.key" -pkeyopt rsa_keygen_bits:2048 | |
if [ $? -ne 0 ]; then | |
printf "${RED}Failed to generate client private key.${NC}\n" | |
return 1 | |
fi | |
# Generate a certificate signing request (CSR) for the client | |
openssl req -new -key "${client_filename}.key" -out "${client_filename}.csr" -subj "/C=US/ST=State/L=City/O=Organization/OU=Org Unit/CN=${client_cn}/emailAddress=${client_email}" | |
if [ $? -ne 0 ]; then | |
printf "${RED}Failed to generate client CSR.${NC}\n" | |
return 1 | |
fi | |
# Sign the client CSR with the CA certificate to create the client certificate | |
openssl x509 -req -in "${client_filename}.csr" -CA ca.crt -CAkey ca.key -CAcreateserial -out "${client_filename}.crt" -days 365 | |
if [ $? -ne 0 ]; then | |
printf "${RED}Failed to generate client certificate.${NC}\n" | |
return 1 | |
fi | |
# Generate a PKCS#12 (P12) file containing the client certificate and key | |
openssl pkcs12 -export -out "${client_filename}.p12" -inkey "${client_filename}.key" -in "${client_filename}.crt" -passout pass:changeit | |
if [ $? -ne 0 ]; then | |
printf "${RED}Failed to generate client P12 file.${NC}\n" | |
return 1 | |
fi | |
printf "${GREEN}Client certificate and P12 file created successfully.${NC}\n" | |
} | |
# Function to change the password for the truststore | |
change_truststore_password() { | |
printf "${GREEN}Changing truststore password...${NC}\n" | |
# Prompt for the current and new passwords | |
read -sp "Enter the current truststore password (default - changeit): " current_password | |
printf "\n" | |
read -sp "Enter the new truststore password: " new_password | |
printf "\n" | |
read -sp "Confirm the new truststore password: " confirm_password | |
printf "\n" | |
# Check if the new passwords match | |
if [ "$new_password" != "$confirm_password" ]; then | |
printf "${RED}New passwords do not match. Password change aborted.${NC}\n" | |
return | |
fi | |
# Change the password for the truststore | |
keytool -storepasswd -keystore truststore.jks -storepass "$current_password" -new "$new_password" | |
if [ $? -ne 0 ]; then | |
printf "${RED}Failed to change truststore password.${NC}\n" | |
return 1 | |
fi | |
printf "${GREEN}Truststore password changed successfully.${NC}\n" | |
} | |
# Function to change the password for a P12 file | |
change_p12_password() { | |
printf "${GREEN}Changing P12 password...${NC}\n" | |
# List all P12 files in the current directory | |
p12_files=(*.p12) | |
if [ ${#p12_files[@]} -eq 0 ]; then | |
printf "${RED}No P12 files found in the current directory.${NC}\n" | |
return 1 | |
fi | |
printf "${YELLOW}Select a P12 file to change the password:${NC}\n" | |
select p12_file in "${p12_files[@]}"; do | |
if [ -n "$p12_file" ]; then | |
break | |
else | |
printf "${RED}Invalid selection. Please try again.${NC}\n" | |
fi | |
done | |
# Prompt for the current and new passwords | |
read -sp "Enter the current P12 password (default - changeit): " current_password | |
printf "\n" | |
read -sp "Enter the new P12 password: " new_password | |
printf "\n" | |
read -sp "Confirm the new P12 password: " confirm_password | |
printf "\n" | |
# Check if the new passwords match | |
if [ "$new_password" != "$confirm_password" ]; then | |
printf "${RED}New passwords do not match. Password change aborted.${NC}\n" | |
return | |
fi | |
# Change the password for the P12 file | |
openssl pkcs12 -in "$p12_file" -out temp.pem -passin pass:"$current_password" -passout pass:"$new_password" | |
if [ $? -ne 0 ]; then | |
printf "${RED}Failed to extract P12 content.${NC}\n" | |
rm -f temp.pem | |
return 1 | |
fi | |
openssl pkcs12 -export -in temp.pem -out "$p12_file" -passin pass:"$new_password" -passout pass:"$new_password" | |
if [ $? -ne 0 ]; then | |
printf "${RED}Failed to re-export P12 file.${NC}\n" | |
rm -f temp.pem | |
return 1 | |
fi | |
rm -f temp.pem | |
printf "${GREEN}P12 password changed successfully.${NC}\n" | |
} | |
verify_certificates() { | |
printf "${BLUE}Verifying certificates in the current folder...${NC}\n" | |
local ca_cert="ca.crt" | |
if [ ! -f "$ca_cert" ]; then | |
printf "${RED}CA certificate '$ca_cert' not found. Please ensure 'ca.crt' is in the current directory.${NC}\n" | |
return | |
fi | |
for cert_file in *.crt; do | |
if [ -f "$cert_file" ]; then | |
if [ "$cert_file" == "server.crt" ]; then | |
printf "${YELLOW}Verifying $cert_file as server certificate...${NC}\n" | |
openssl verify -CAfile "$ca_cert" -purpose sslserver "$cert_file" | |
else | |
printf "${YELLOW}Verifying $cert_file as client certificate...${NC}\n" | |
openssl verify -CAfile "$ca_cert" -purpose sslclient "$cert_file" | |
fi | |
else | |
printf "${RED}No certificate files found in the current directory.${NC}\n" | |
fi | |
done | |
} | |
check_file_exists() { | |
local filename=$1 | |
if [ -f "$filename" ]; then | |
echo true | |
else | |
echo false | |
fi | |
} | |
# Function to display the menu | |
show_menu() { | |
printf "${BLUE}Select an option:${NC}\n" | |
printf "${YELLOW}1. Create CA Certificate${NC}\n" | |
printf "${YELLOW}2. Create Server Certificate${NC}\n" | |
printf "${YELLOW}3. Create Client Certificate${NC}\n" | |
printf "${YELLOW}4. Change Truststore Password${NC}\n" | |
printf "${YELLOW}5. Change P12 Password${NC}\n" | |
printf "${YELLOW}6. Verify Certificates${NC}\n" | |
printf "${YELLOW}7. Exit${NC}\n" | |
} | |
# Main script logic | |
while true; do | |
show_menu | |
read -p "Enter your choice [1-7]: " choice | |
case $choice in | |
1) | |
create_ca_certificate | |
;; | |
2) | |
create_server_certificate | |
;; | |
3) | |
create_client_certificate | |
;; | |
4) | |
change_truststore_password | |
;; | |
5) | |
change_p12_password | |
;; | |
6) | |
verify_certificates | |
;; | |
7) | |
printf "${RED}Exiting...${NC}\n" | |
exit 0 | |
;; | |
*) | |
printf "${RED}Invalid option. Please try again.${NC}\n" | |
;; | |
esac | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment