#!/bin/bash ################################################################################ # Intended use: Simple shell script to create certs (RSA or EC) # # Notes: This script support Linux Bash shell script only # Install Bash from https://www.gnu.org/software/bash/ # # Copyright (C) 2015 - 2025, VGISC Dev Team ################################################################################ filepath=`readlink -f $0` basedir=`dirname $filepath` SCRIPT_DIR=`dirname $filepath` FLAG_EC=0 COMMON_ARGS="-batch" DOMAIN="vgisc.com" OPENSSL_BIN="$basedir/bin/openssl" init_dir(){ if [ -f "$basedir/root-ca" ]; then return fi mkdir -p $basedir/{root-ca,sub-ca}/{db,certs,private} touch $basedir/{root-ca,sub-ca}/db/index touch $basedir/{root-ca,sub-ca}/db/index.attr chmod 700 $basedir/{root-ca,sub-ca}/private $OPENSSL_BIN rand -hex 16 > $basedir/root-ca/db/serial $OPENSSL_BIN rand -hex 16 > $basedir/sub-ca/db/serial echo 1001 > $basedir/root-ca/db/crlnumber echo 1001 > $basedir/sub-ca/db/crlnumber cp $basedir/conf/root-ca.conf $basedir/root-ca/root-ca.conf cp $basedir/conf/sub-ca.conf $basedir/sub-ca/sub-ca.conf } gen_ca() { if [ -f "$basedir/root-ca/root-ca.crt" ];then echo "Root CA is present, please delete it or run build.sh clean before generate a new root CA" return fi init_dir cd $basedir/root-ca if [ $FLAG_EC -eq 0 ];then $OPENSSL_BIN req -new -config root-ca.conf -out root-ca.csr -keyout private/root-ca.key -nodes $OPENSSL_BIN rsa -in private/root-ca.key -out private/root-ca.key else $OPENSSL_BIN ecparam -genkey -name secv384 -out private/root-ca.key $OPENSSL_BIN req -new -config root-ca.conf -key private/root-ca.key -out root-ca.csr $OPENSSL_BIN ec -in private/root-ca.key -out private/root-ca.key fi $OPENSSL_BIN ca $COMMON_ARGS -selfsign -config root-ca.conf -rand_serial\ -in root-ca.csr -out root-ca.crt\ -extensions ca_ext } gen_subca() { if [ -f "$basedir/sub-ca/sub-ca.crt" ];then echo "Sub CA is present, please delete it or run build.sh clean before generate a new sub CA" return fi if [ ! -f "$basedir/root-ca/root-ca.crt" ];then echo "Root CA not present... Building CA now..." gen_ca fi cd $basedir/sub-ca if [ $FLAG_EC -eq 0 ]; then $OPENSSL_BIN req -new -config sub-ca.conf -nodes\ -out sub-ca.csr -keyout private/sub-ca.key else $OPENSSL_BIN ecparam -genkey -name secv384 -out private/sub-ca.key $OPENSSL_BIN req -new -config sub-ca.conf -key private/sub-ca.key -out sub-ca.csr fi cd $basedir/root-ca $OPENSSL_BIN ca $COMMON_ARGS -config root-ca.conf -rand_serial\ -in $basedir/sub-ca/sub-ca.csr -out $basedir/sub-ca/sub-ca.crt\ -extensions sub_ca_ext } server() { if [ ! -f "$basedir/sub-ca/sub-ca.crt" ];then echo "Sub CA not present... Building Sub CA now..." gen_subca fi mkdir -p $basedir/server cp $basedir/conf/openssl.cnf $basedir/server/ cd $basedir/server CN=$1 if [ $FLAG_EC -eq 0 ]; then $OPENSSL_BIN req -config openssl.cnf -new -nodes\ -out "$CN.csr" -keyout "$CN.key"\ -subj "/C=VN/ST=Ha Noi/L=Dong Da/O=VGISC/CN=$CN"\ -addext "subjectAltName=DNS:$CN,DNS:*.$CN" else $OPENSSL_BIN ecparam -genkey -name secv384 -out "$CN.key" $OPENSSL_BIN req -config openssl.cnf -new\ -key "$CN.key" -out "$CN.csr"\ -subj "/C=VN/ST=Ha Noi/L=Dong Da/O=VGISC/CN=$CN"\ -addext "subjectAltName=DNS:$CN,DNS:*.$CN" fi cd $basedir/sub-ca $OPENSSL_BIN ca $COMMON_ARGS -config sub-ca.conf -rand_serial\ -in $basedir/server/$CN.csr -out $basedir/server/$CN.crt\ -extensions server_ext cat sub-ca.crt >> $basedir/server/$CN.crt } client() { if [ ! -f "$basedir/sub-ca/sub-ca.crt" ];then echo "Sub CA not present... Building Sub CA now..." gen_subca fi mkdir -p $basedir/client cp $basedir/conf/openssl.cnf $basedir/client/ cd $basedir/client CN=$1 if [ $FLAG_EC -eq 0 ]; then $OPENSSL_BIN req -config openssl.cnf -new -nodes\ -out "$CN.csr" -keyout "$CN.key"\ -subj "/C=VN/ST=Ha Noi/L=Dong Da/O=VGISC/CN=$CN" else $OPENSSL_BIN ecparam -genkey -name secv384 -out "$CN.key" $OPENSSL_BIN req -config openssl.cnf -new\ -out "$CN.csr" -key "$CN.key"\ -subj "/C=VN/ST=Ha Noi/L=Dong Da/O=VGISC/CN=$CN" fi cd $basedir/sub-ca $OPENSSL_BIN ca $COMMON_ARGS -config sub-ca.conf -rand_serial\ -in $basedir/client/$CN.csr -out $basedir/client/$CN.crt\ -extensions client_ext cat sub-ca.crt >> $basedir/client/$CN.crt } test_server() { server test.com cd $basedir # Both the s_server and s_client won't send the full chain, # which differs from what the Web Server and Browser do. # So we have to concatenate the CA and SubCA as a whole cat sub-ca/sub-ca.crt root-ca/root-ca.crt > /tmp/ca-bundle.crt if [ $FLAG_EC -eq 0 ]; then $OPENSSL_BIN s_server -accept 8443 -verify 2 -state\ -CAfile /tmp/ca-bundle.crt\ -cert server/test.com.crt\ -key server/test.com.key else $TEST_OPENSSL_BIN s_server -accept 8443 -verify 2 -state\ -CAfile /tmp/ca-bundle.crt\ -cert server/test.com.crt\ -key server/test.com.key fi } test_client() { client UserTest cd $basedir if [ $FLAG_EC -eq 0 ]; then $OPENSSL_BIN s_client -connect 127.0.0.1:8443\ -verify 2 -state\ -CAfile root-ca/root-ca.crt\ -cert client/UserTest.crt\ -key client/UserTest.key else $TEST_OPENSSL_BIN s_client -connect 127.0.0.1:8443\ -config $basedir/client/openssl.cnf\ -verify 2 -state\ -CAfile root-ca/root-ca.crt\ -cert client/UserTest.crt\ -key client/UserTest.key fi } verify() { cd $basedir for i in `ls server/*.crt client/*.crt`; do echo $OPENSSL_BIN verify -show_chain\ -CAfile root-ca/root-ca.crt -untrusted sub-ca/sub-ca.crt $i done } clean() { rm -rf $basedir/root-ca rm -rf $basedir/sub-ca rm -rf $basedir/server rm -rf $basedir/client rm -rf $basedir/ca.crt } usage() { echo "================================" echo "Usage:" echo " ./build.sh rsa/ec gen_ca # generate CA keys and certs" echo " ./build.sh rsa/ec gen_subca # generate Sub CA keys and certs (implying: gen_ca)" echo " ./build.sh rsa/ec server wwww.vgisc.com # generate Server certs with CommonName: www.test.com (implying: gen_subca)" echo " ./build.sh rsa/ec client vpn1.vgisc.com # generate client certs with CommonName: Client1 (implying: gen_subca)" echo "" echo " ./build.sh rsa/ec test_server # generate a test server cert and run openssl s_server on 127.0.0.1:8443" echo " ./build.sh rsa/ec test_client # generate a test client cert and run openssl s_client connecting 127.0.0.1:8443" echo " ./build.sh verify # verify every cert in ./server/*.crt and ./client/*.crt" echo " ./build.sh clean # delete everything, including root-ca and sub-ca dirs" echo " ./build.sh help # show this help" } help() { usage } if [ $# -eq 0 ]; then help elif [ $# -eq 1 ];then echo "Calling:$1" eval $1 else if [ "$1" = "ec" ];then FLAG_EC=1 fi echo "Calling:$2" eval $2 $3 fi ################################################################################ # BASH SCRIPT ON LINUX/UNIX - END ################################################################################