vgisc-rsa-4096/build.sh
2025-02-24 11:30:30 +07:00

261 lines
6.7 KiB
Bash
Executable file

#!/bin/bash
# Date: 2023-11-04
# Author: Ho Sy Tan <hstan@vgisc.com>
# Description: Simple shell script to create certs (RSA or EC)
filepath=`readlink -f $0`
basedir=`dirname $filepath`
FLAG_EC=0
OPENSSL_BIN="$basedir/bin/openssl"
COMMON_ARGS="-batch"
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()
{
echo -e "OpenSSL binary path: $OPENSSL_BIN"
echo -e "OpenSSL libaray path: $OPENSSL_LIB"
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
# cat $basedir/root-ca/root-ca.crt $basedir/sub-ca/sub-ca.crt > $basedir/ca.crt
}
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