first commit

This commit is contained in:
Gilles Mouchet 2026-04-10 15:53:11 +02:00
commit dea7deead6
11 changed files with 840 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
ca-config

5
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"editor.fontSize": 13,
"terminal.integrated.fontSize": 13,
"window.zoomLevel": 1.4,
}

17
LICENSE Normal file
View File

@ -0,0 +1,17 @@
These scripts are made available under the terms of the Creative Commons Attribution-NonCommercial 4.0 International License.
DISCLAIMER OF WARRANTY:
The scripts are provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and non-infringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability.
To view a copy of this license, visit:
http://creativecommons.org/licenses/by-nc/4.0/
French version
Ces scripts sont mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale 4.0 International.
LIMITATION DE GARANTIE :
Les scripts sont fournis « en l'état », sans garantie d'aucune sorte, expresse ou implicite, y compris, mais sans s'y limiter, les garanties de qualité marchande, d'adéquation à un usage particulier et d'absence de contrefaçon. En aucun cas, les auteurs ou les détenteurs de droits d'auteur ne pourront être tenus responsables de toute réclamation, dommage ou autre responsabilité.
Pour voir une copie de cette licence, visitez :
http://creativecommons.org/licenses/by-nc/4.0/

0
README.md Normal file
View File

102
ca-config.tmpl Normal file
View File

@ -0,0 +1,102 @@
HOME = .
RANDFILE = $ENV::HOME/.rnd
oid_section = new_oids
[ new_oids ]
[ ca ]
default_ca = CA_default # The default ca section
[ CA_default ]
dir = . # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/dbca/index.txt # database index file.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial/serial # The current serial number
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem# The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
default_days = 365 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = md5 # which md to use.
preserve = no # keep passed DN ordering
policy = policy_match
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
default_bits = 1024
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
string_mask = nombstr
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = %COUNTRY_NAME%
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = %STATE_OF_PROVINCE_NAME%
localityName = Locality Name (eg, city)
localityName_default = %LOCALITY_NAME%
0.organizationName = Organization Name (eg, company)
0.organizationName_default = %ORGANIZITION_NAME%
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = %ORGANiZATION_UNIT_NAME%
commonName = Common Name (eg, YOUR name)
commonName_default = %COMMON_NAME%
commonName_max = 64
emailAddress = Email Address
emailAddress_default = %EMAIL_ADDRESS%
emailAddress_max = 40
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name
[ usr_cert ]
basicConstraints=CA:FALSE
nsComment = "OpenSSL Generated Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
basicConstraints = CA:true
[ crl_ext ]
authorityKeyIdentifier=keyid:always,issuer:always

177
create-CA.sh Executable file
View File

@ -0,0 +1,177 @@
#!/bin/bash
#############################################################
# Script name: createCA.sh
# Author: Gilles Mouchet (gilles.mouchet@gmail.com
# Version: v1beta 2026-04-05
# Description: Script to create a own CA
# License: CC BY-NC 4.0 (https://creativecommons.org/licenses/by-nc/4.0/)
#
# This script is provided "as is", WITHOUT ANY WARRANTY OF ANY KIND.
# Commercial use is strictly prohibited without prior authorization.
#
# Changelog
# [1.0.0] - 2026-04-05
# Project initialization
# - initialization by gilles.mouchet@gmail.com
#
############################################################
#
version=v1beta
############################################################
# FUNCTIONS
############################################################
#-----------------------------------------------------------
# Display usage
usage() {
cat << EOF
Usage: ./$(basename "$0") -n <commonName>
Template script
Options:
-n, --common-name - CA common name [mandatory]
-h, --help - show this help
-v, --version - show script version
Examples:
Show this help
./$(basename "$0") -n "GMOLab CA"
EOF
}
#-----------------------------------------------------------
clean_string() {
echo "$1" | \
# translite special chars to closest ASCII (e.g., 'é' -> 'e')
iconv -f utf-8 -t ascii//TRANSLIT | \
# convert to lowercase
tr '[:upper:]' '[:lower:]' | \
# replace any non-alphanumeric character with an underscore
sed -E 's/[^a-z0-9]+/_/g' | \
# replace multiple underscores into one
sed -E 's/(_)+/_/g' | \
# remove underscores at the beginning or end
sed -E 's/^_|_$//g'
}
############################################################
# MAIN
############################################################
# var for config file
progName=`echo $0 | sed -e 's|.*/||g' | cut -f1 -d.`
confDir=/etc/own-pki
cfgFile=${confDir}/own-pki.conf
# check if conf file or passphrase file exist
if [ ! -f $cfgFile ]; then
echo "$progName not installed correctly. Please run install.sh script"
exit 1
fi
# read config file
. $cfgFile
# check if param exist
if [ -z "$1" ]; then
usage
exit 1
fi
# read cli parameters
while [[ "$#" -gt 0 ]]; do
case "$1" in
-n|--name)
# check if param $2 exist
if [ -z "$2" ]; then
usage
exit
else
commonName="$2"
fi
shift 2
;;
version|-v|--version)
cat << EOF
$(basename "$0") $version (c) 1990 - $(date +%Y) by Gilles Mouchet
This script is provided "as is", WITHOUT ANY WARRANTY OF ANY KIND.
Non-Commercial Use License See LICENSE for details
EOF
exit
;;
*|help|-h|--help)
usage
exit
;;
esac
done
# clean variable commonName
caName=$(clean_string "${commonName}")
# summary
cat << EOF
Summary
----------------------------------------------------------------------------
Certificats files destination: $certPath
CA private file name (key): $certPath/$caName.key
CA public file name (crt): $certPath/$caName.crt
Country name: $countryName
State or province name: $stateOrProvinceName
Locality name: $localityName
Organization name: $organizationName
Organizational unit name: $organizationalUnitName
Common name: $commonName
Email address: $emailAddress
IMPORTANT
You will be asked for a password. Choose a STRONG PASSWORD
and KEEP IT SECURE.
You will be asked for it when creating certificates.
EOF
read -p "Are you OK (y/N)? " answer
if [[ "$answer" != "y" && "$answer" != "Y" ]]; then
exit 1
fi
# create destination path
if [ ! -d "$certPath" ]; then
echo "create $certPath"
mkdir $certPath
fi
# check if CA files exist
if [ -f "$certPath/$caName.key" ]; then
echo -e "\n$certPath/$caName.key already exists!\n"
read -p "Are you sure you want to delete it? (y/N)? " answer
if [[ "$answer" != "y" && "$answer" != "Y" ]]; then
exit 1
fi
fi
# config ca-conf file
sed -e "s|%COUNTRY_NAME%|$countryName|" \
-e "s|%STATE_OF_PROVINCE_NAME%|$stateOrProvinceName|" \
-e "s|%LOCALITY_NAME%|$localityName|" \
-e "s|%ORGANIZITION_NAME%|$organizationName|" \
-e "s|%ORGANiZATION_UNIT_NAME%|$organizationalUnitName|" \
-e "s|%COMMON_NAME%|$commonName|" \
-e "s|%EMAIL_ADDRESS%|$emailAddress|" < ca-config.tmpl > $certPath/ca-config
# create ca
openssl req -new -x509 -extensions v3_ca -days 1825 -newkey rsa:4096 \
-keyout $certPath/$caName.key \
-out $certPath/$caName.crt \
-config $certPath/ca-config \
-batch
if [ "$?" == "0" ]; then
echo "CA created successfully"
echo "!! Keep your password safe !!"
fi

228
generate-cert.sh Executable file
View File

@ -0,0 +1,228 @@
#!/bin/bash
#############################################################
# Script name: template.sh
# Author: Gilles Mouchet (gilles.mouchet@gmail.com
# Version: v1beta 2026-04-05
# Description: Script template linux
# License: CC BY-NC 4.0 (https://creativecommons.org/licenses/by-nc/4.0/)
#
# This script is provided "as is", WITHOUT ANY WARRANTY OF ANY KIND.
# Commercial use is strictly prohibited without prior authorization.
#
# Changelog
# [1.0.0] - 2026-04-05
# Project initialization
# - initialization by gilles.mouchet@gmail.com
#
############################################################
#
version=v1beta
days=365
############################################################
# FUNCTIONS
############################################################
#-----------------------------------------------------------
# Display usage
usage() {
cat << EOF
Usage: $0 -c <ca_cert> -k <ca_key> -n <common_name> [-d <dns1,dns2>] [-i <ip1,ip2>] [-t <days>]"
Template script
Options:
-c, --ca-name - ca name
-n, --commonName - common name (server.domain.ext)
-d, --dns - subject alternative name (multiple SAN separated by commas)
-i, --ip - ip address to add to the certificate (multiple IPs separated by commas)
-t, --days - validity period of the certificate in days (defaults $days days)
-h, --help - show this help
-v, --version - show script version
Examples:
Generate a certificate for myweb.gmolab.net
./$(basename "$0") -c gmolab_ca -n myweb.gmolab.net
Generate a certifciate for myweb.gmolab.net with dns alias and ip
./$(basename "$0") -c gmolab_ca -n myweb.gmolab.net -i 92.168.1.10,10.0.0.5,10.10.34.25 --dns www.gmolab.net,qual-myweb.gmolab.net -t 49
Show this help
./$(basename "$0") -h
EOF
}
############################################################
# MAIN
############################################################
# var for config file
progName=`echo $0 | sed -e 's|.*/||g' | cut -f1 -d.`
confDir=/etc/own-pki
cfgFile=${confDir}/own-pki.conf
# check if conf file or passphrase file exist
if [ ! -f $cfgFile ]; then
echo "$progName not installed correctly. Please run install.sh script"
exit 1
fi
# read config file
. $cfgFile
# check if param exist
if [ -z "$1" ]; then
usage
exit 1
fi
# parse cli parameters
while [[ "$#" -gt 0 ]]; do
case "$1" in
-c|--ca-name)
ca_crt=$2.crt
ca_key=$2.key
shift 2
;;
-n|--common-name)
if [[ ! $2 =~ ^([a-z0-9]+(-[a-z0-9]+)*\.){2,}[a-z]{2,}$ ]]; then
echo -e "\n$2 is not a commonName valid\n"
usage
exit 1
else
commonName=$2
fi
shift 2
;;
-d|--dns)
IFS=',' read -r -a dns <<< "$2"
shift 2
;;
-i|--ip)
IFS=',' read -r -a ipAddrs <<< "$2"
shift 2
;;
-t|--days)
days=$2
shift 2
;;
version|-v|--version)
cat << EOF
$(basename "$0") $version (c) 1990 - $(date +%Y) by Gilles Mouchet
This script is provided "as is", WITHOUT ANY WARRANTY OF ANY KIND.
Non-Commercial Use License See LICENSE for details
EOF
exit
;;
*|help|-h|--help)
usage
exit
;;
esac
done
# check
if [[ -z "$ca_crt" || -z "$ca_key" || -z "$commonName" ]]; then
usage
exit 1
fi
# check if ca key and ca crt exist
if [[ ! -f "$certPath/$ca_crt" || ! -f "$certPath/$ca_key" ]]; then
cat << EOF
One or both of the following files are missing:
- $certPath/$ca_crt
- $certPath/$ca_key
EOF
exit 1
fi
cat << EOF
Summary
---------------------------------------------------------------------
Certifcate authority: $ca_crt
Common name: $commonName
EOF
echo "SAN List:"
echo " - ${commonName}"
for san in "${dns[@]}"; do
echo " - $san"
done
echo "IP List:"
for ip in "${ipAddrs[@]}"; do
if [[ $ip =~ ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]]; then
echo " - $ip"
else
echo " - $ip is not valid !"
fi
done
echo "Validity:"
echo " Not before: $(date +"%b %d %H:%M:%S %Y GMT")"
echo " Not After : $(date -u -d "+$days days" +"%b %d %H:%M:%S %Y GMT")"
read -p "Are you OK (y/N)? " answer
if [[ "$answer" != "y" && "$answer" != "Y" ]]; then
exit 1
fi
echo -e "\nPrepare the openSSL configuration file"
cat > "$certPath/${commonName}_openssl.cnf" << EOF
[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
req_extensions = req_ext
prompt = no
[ req_distinguished_name ]
CN = $commonName
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
EOF
echo -e " Add SAN"
# add dns
i=1
echo "DNS.$i = ${commonName}" >> "$certPath/${commonName}_openssl.cnf"
((i++))
for san in "${dns[@]}"; do
echo "DNS.$i = $san" >> "$certPath/${commonName}_openssl.cnf"
((i++))
done
echo -e " Add IP"
# add ip
i=1
for ip in "${ipAddrs[@]}"; do
if [[ $ip =~ ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]]; then
echo "IP.$i = $ip" >> "$certPath/${commonName}_openssl.cnf"
((i++))
else
echo -e "\nAddress ip $ip is not valid\n"
((i++))
fi
done
echo -e "\nGenerating the private key..."
openssl genrsa -out "${certPath}/${commonName}.key" 4096
echo -e "\nGenerating csr file..."
openssl req -new -key "${certPath}/${commonName}.key" -out "${certPath}/${commonName}.csr" -config "$certPath/${commonName}_openssl.cnf"
echo -e "\nSigning the certificate with the CA...\n"
openssl x509 -req -in "${certPath}/${commonName}.csr" \
-CA "$certPath/$ca_crt" -CAkey "$certPath/$ca_key" -CAcreateserial \
-out "${certPath}/${commonName}.crt" -days "$days" \
-extensions req_ext -extfile "$certPath/${commonName}_openssl.cnf"
echo -e "\nVerify certifcate"
echo -e "\nValidity"
openssl x509 -in $certPath/$commonName.crt -noout -dates
echo -e "\nSubject Alternative Name"
openssl x509 -in $certPath/$commonName.crt -noout -ext subjectAltName
echo -e "\nVerify the validity of a certificate using the trust chain"
openssl verify -CAfile $certPath/$ca_crt $certPath/$commonName.crt

123
info-cert.sh Executable file
View File

@ -0,0 +1,123 @@
#!/bin/bash
#############################################################
# Script name: template.sh
# Author: Gilles Mouchet (gilles.mouchet@gmail.com
# Version: v1beta 2026-04-05
# Description: Script template linux
# License: CC BY-NC 4.0 (https://creativecommons.org/licenses/by-nc/4.0/)
#
# This script is provided "as is", WITHOUT ANY WARRANTY OF ANY KIND.
# Commercial use is strictly prohibited without prior authorization.
#
# Changelog
# [1.0.0] - 2026-04-05
# Project initialization
# - initialization by gilles.mouchet@gmail.com
#
############################################################
#
version=v1beta
############################################################
# FUNCTIONS
############################################################
#-----------------------------------------------------------
# Display usage
usage() {
cat << EOF
Usage: ./$(basename "$0") options
Template script
Options:
-a, --all - show all cert information
-c, --list-ca - list all CA name
-h, --help - show this help
-v, --version - show script version
Examples:
List all CA name
./$(basename "$0") --list-ca
Show this help
./$(basename "$0") -h
List
EOF
}
############################################################
# MAIN
############################################################
# var for config file
progName=`echo $0 | sed -e 's|.*/||g' | cut -f1 -d.`
confDir=/etc/own-pki
cfgFile=${confDir}/own-pki.conf
# check if conf file or passphrase file exist
#if [ ! -f $cfgFile ]; then
# echo "$progName not installed correctly. Please run install.sh script"
# exit 1
#fi
# read config file
. $cfgFile
# check if param exist
if [ -z "$1" ]; then
usage
exit 1
fi
# read cli parameters
while [[ "$#" -gt 0 ]]; do
case "$1" in
-a|--all)
files=( $certPath/*.crt )
for f in "${files[@]}"; do
openssl x509 -in $f -text -noout | grep "CA:TRUE" > /dev/null
if [ "$?" == "1" ]; then
filename=$(basename "$f" .crt)
#echo "CA name: $filename"
commonName=$(openssl x509 -in $f -noout -subject -nameopt RFC2253 | sed -n 's/^.*CN=\([^,]*\).*$/\1/p')
# Infos principales
#subject=$(openssl x509 -in "$f" -noout -subject -nameopt RFC2253 | sed 's/^subject=//')
issuer=$(openssl x509 -in "$f" -noout -issuer -nameopt RFC2253 | sed 's/^issuer=//')
startdate=$(openssl x509 -in "$f" -noout -startdate | cut -d= -f2)
enddate=$(openssl x509 -in "$f" -noout -enddate | cut -d= -f2)
# SAN brut
san_raw=$(openssl x509 -in "$f" -noout -text \
| awk '/Subject Alternative Name/ {getline; print}')
# dns and ip extraction
dns_list=$(echo "$san_raw" | grep -o 'DNS:[^,]*' | sed 's/DNS://g'| tr '\n' ' '| sed 's/ $//')
ip_list=$(echo "$san_raw" | grep -o 'IP Address:[^,]*' | sed 's/IP Address://g'| tr '\n' ' '| sed 's/ $//')
echo "\"$f\";\"$commonName\";\"$issuer'\";\"$dns_list\";\"$ip_list\";\"$startdate\";\"$enddate\""
fi
done
shift
;;
-c|--list-ca)
files=( $certPath/*.crt )
for f in "${files[@]}"; do
openssl x509 -in $f -text -noout | grep "CA:TRUE" > /dev/null
if [ "$?" == "0" ]; then
filename=$(basename "$f" .crt)
echo "CA name: $filename"
fi
done
shift
;;
version|-v|--version)
cat << EOF
$(basename "$0") $version (c) 1990 - $(date +%Y) by Gilles Mouchet
This script is provided "as is", WITHOUT ANY WARRANTY OF ANY KIND.
Non-Commercial Use License See LICENSE for details
EOF
exit
;;
*|help|-h|--help)
usage
exit
;;
esac
done

81
install.sh Executable file
View File

@ -0,0 +1,81 @@
#!/bin/bash
#############################################################
# Script name: install.sh
# Author: Gilles Mouchet (gilles.mouchet@gmail.com
# Version: v1beta 2026-04-05
# Description: This script prepare own pki environment
# License: CC BY-NC 4.0 (https://creativecommons.org/licenses/by-nc/4.0/)
#
# This script is provided "as is", WITHOUT ANY WARRANTY OF ANY KIND.
# Commercial use is strictly prohibited without prior authorization.
#
# Changelog
# [1.0.0] - 2026-04-05
# Project initialization
# - initialization by gilles.mouchet@gmail.com
#
############################################################
#
version=v1beta
cfgPath="/etc/own-pki"
############################################################
# FUNCTIONS
############################################################
#-----------------------------------------------------------
# Display usage
usage() {
cat << EOF
Usage: sudo ./$(basename "$0") options
Template script
Options:
-h, --help - show this help
-v, --version - show script version
Examples:
Show this help
sudo ./$(basename "$0") -h
EOF
}
############################################################
# MAIN
############################################################
# check if the effective user ID is 0 (root)
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root or with sudo."
exit 1
fi
# read cli parameters
while [[ "$#" -gt 0 ]]; do
case "$1" in
version|-v|--version)
cat << EOF
$(basename "$0") $version (c) 1990 - $(date +%Y) by Gilles Mouchet
This script is provided "as is", WITHOUT ANY WARRANTY OF ANY KIND.
Non-Commercial Use License See LICENSE for details
EOF
exit
;;
*|help|-h|--help)
usage
exit
;;
esac
done
if [ ! -d "$cfgPath" ]; then
echo "create $cfgPath"
mkdir $cfgPath
fi
cp own-pki.conf.tmpl $cfgPath/own-pki.conf
echo "*****************************************************"
echo " Installation completed !!"
echo " Adapt the file $cfgPath/own-pki.cfg as you need"
echo "*****************************************************"

26
own-pki.conf.tmpl Normal file
View File

@ -0,0 +1,26 @@
# paths where the certificate was stored
certPath=~/own-pki
# variables to use for create ca-config file
# country Name (2 letter code)
countryName=CH
#State or province name (full name)
stateOrProvinceName=Vaud
# locality name (eg, city)
localityName=Nyon
# organization name (eg, company)
organizationName="GMO Lab (gmolab)"
# organizational Unit Name (eg, section)
organizationalUnitName="ITCS (Information Technology and Communications Service)"
# NOT USE. SET WITH PARAM -n from createCA.sh script
# common Name (eg, YOUR name)
#commonName="GMOLab CA"
# email address
emailAddress=example@example.com

80
template.sh Executable file
View File

@ -0,0 +1,80 @@
#!/bin/bash
#############################################################
# Script name: template.sh
# Author: Gilles Mouchet (gilles.mouchet@gmail.com
# Version: v1beta 2026-04-05
# Description: Script template linux
# License: CC BY-NC 4.0 (https://creativecommons.org/licenses/by-nc/4.0/)
#
# This script is provided "as is", WITHOUT ANY WARRANTY OF ANY KIND.
# Commercial use is strictly prohibited without prior authorization.
#
# Changelog
# [1.0.0] - 2026-04-05
# Project initialization
# - initialization by gilles.mouchet@gmail.com
#
############################################################
#
version=v1beta
############################################################
# FUNCTIONS
############################################################
#-----------------------------------------------------------
# Display usage
usage() {
cat << EOF
Usage: ./$(basename "$0") options
Template script
Options:
-h, --help - show this help
-v, --version - show script version
Examples:
Show this help
./$(basename "$0") -h
EOF
}
############################################################
# MAIN
############################################################
# var for config file
progName=`echo $0 | sed -e 's|.*/||g' | cut -f1 -d.`
confDir=/etc/$progName
cfgFile=${confDir}/$progName.conf
# check if conf file or passphrase file exist
if [ ! -f $cfgFile ]; then
echo "$progName not installed correctly. Please run install.sh script"
exit 1
fi
# read config file
. $cfgFile
# check if param exist
if [ -z "$1" ]; then
usage
exit 1
fi
# read cli parameters
while [[ "$#" -gt 0 ]]; do
case "$1" in
version|-v|--version)
cat << EOF
$(basename "$0") $version (c) 1990 - $(date +%Y) by Gilles Mouchet
This script is provided "as is", WITHOUT ANY WARRANTY OF ANY KIND.
Non-Commercial Use License See LICENSE for details
EOF
exit
;;
*|help|-h|--help)
usage
exit
;;
esac
done