MOD: moving functions to a seperate script, organizing and modifying the lifecycle scripts

This commit is contained in:
JohnE 2018-08-08 12:30:59 -07:00
parent 8510375d68
commit 23bc9f2e7c
8 changed files with 164 additions and 372 deletions

38
README
View File

@ -12,11 +12,16 @@
This package contains a set of programs to generate an entire certificate chain of trust This package contains a set of programs to generate an entire certificate chain of trust
and will configure StrongSwan server. .p12 files are generated for client distribution. and will configure StrongSwan server. .p12 files are generated for client distribution.
Features: There are two main applications contained in this project.
* Certificate Authority (CA) creation * MOB Hub System : PKI Bootstrap
* Server and Client certificate generation (based on CA) - 1 x Certificate Authority (CA) generation
* CA and Client certificate packaged as .p12 file for easy import to Android (other clients too) - 5 x CA Intermediate generation
* Ubuntu networking configuration scripts (tunneling enabled) - 10 x Server and Client certificate generation (based on CA-I)
- CA, CA-I, Server, and Client certificate packaged as .p12 file for easy import to Android (other clients too)
* MOB Hub System : PKI Lifecycle
- Unlimited CA Intermediate generation
- Unlimited Server and Client generation (based on CA-I)
@ -24,12 +29,13 @@ Features:
VERSIONS VERSIONS
--------------------- ---------------------
Version 3.1 - MOB Hub PKI Ver 3.2 - MOB Hub PKI Lifecycle
* PKI Bootstrap
- generate an entire chain-of-trust
* PKI Lifecycle * PKI Lifecycle
- generate certificates during the CA's lifecycle - generate certificates during the CA's lifecycle
Version 3.0 - CA Intermediate Support Ver 3.1 - MOB Hub PKI Bootstrap
* PKI Bootstrap
- generate an entire chain-of-trust
Ver 3.0 - CA Intermediate Support
* requires openssl (does not require ipsec) * requires openssl (does not require ipsec)
* CA Intermediate support * CA Intermediate support
-root CA can be generated with 5-10yr expiration, put into cold-storage -root CA can be generated with 5-10yr expiration, put into cold-storage
@ -61,17 +67,3 @@ Make sure your server date is within the CA, and Server certificate valid date.
---------------- ----------------
------------
HISTORY
------------
version 3.x
* strongswan: new configuration that uses DN (distinguished name) to authenticate clients
(previous configs used local IP address for authentication)
* certificate generation moved to another repository
- separated into two stages
stage 1 : pki bootstrap
stage 2 : pki lifecycle

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# #
# ACME Certificate Bootstrap v1.3 # ACME PKI (Certificate) Bootstrap v1.3
# #
# This script will generate all the files necessary to build a certificate chain of trust # This script will generate all the files necessary to build a certificate chain of trust
# using a CA, CA Intermediate, Server, and Client certificates. After the bootstrap the other # using a CA, CA Intermediate, Server, and Client certificates. After the bootstrap the other
@ -14,9 +14,9 @@ usage() {
echo "using a CA, CA Intermediate, Server, and Client certificates. After the bootstrap the other" echo "using a CA, CA Intermediate, Server, and Client certificates. After the bootstrap the other"
echo "helper scripts will generate new certificates" echo "helper scripts will generate new certificates"
echo echo
echo "Usage: cert_bootstrap <.cnf file (minus the .cnf)>" echo "Usage: pki_bootstrap <.cnf file (minus the .cnf)>"
echo echo
echo "Example: cert_bootstrap org.acme.xyz" echo "Example: pki_bootstrap org.acme.xyz"
exit 1 exit 1
} }
@ -240,20 +240,20 @@ organize() {
# #
gen_pki_certs() { gen_pki_certs() {
B_SERIAL=$1 B_SERIAL=$1
NUM_CERTS=$2 NUM_CERTS=$(($2-1))
# Create CA Intermediate # Create CA Intermediate
UNIQ_ID_CA="${B_SERIAL}.${ORG_URL}" UNIQ_ID_CA="${B_SERIAL}.${ORG_URL}"
generate_ca_i $UNIQ_ID_CA $B_SERIAL generate_ca_i $UNIQ_ID_CA $B_SERIAL
# Server Certificates # Server Certificates
for NUM in $(seq 1 $2) for NUM in $(seq 0 $NUM_CERTS)
do do
generate_server "$((B_SERIAL+NUM)).${ORG_URL}" $UNIQ_ID_CA $((B_SERIAL+NUM)) generate_server "$((B_SERIAL+NUM)).${ORG_URL}" $UNIQ_ID_CA $((B_SERIAL+NUM))
done done
# Client Certificates # Client Certificates
for NUM in $(seq 1 $2) for NUM in $(seq 0 $NUM_CERTS)
do do
generate_client "$((B_SERIAL+NUM)).${ORG_URL}" $UNIQ_ID_CA $((B_SERIAL+NUM)) generate_client "$((B_SERIAL+NUM)).${ORG_URL}" $UNIQ_ID_CA $((B_SERIAL+NUM))
done done

View File

@ -0,0 +1,137 @@
#!/bin/bash
#
# all main functions to generate a PKI certificate chain
#
echo_block() {
echo
echo
echo "***** ***** ***** *****"
echo $1
echo "***** ***** ***** *****"
}
# ***** ***** ***** ***** *****
#
# CERTIFICATE AUTHORITY (CA)
#
# ***** ***** ***** ***** *****
# This function will generate a CA Intermediate
# IN: UNIQ_ID_CA, SERIAL
#
generate_ca() {
# params
UNIQ_ID_CA=$1
SERIAL=$2
# encrypt the key
#openssl genrsa -aes256 -out ca.keys.pem 4096
#openssl genrsa -aes256 -password "pass:password" -out ca.keys.pem 4096
# key un-protected
openssl genrsa -out "ca_${UNIQ_ID_CA}.keys.pem" 4096
#
# Create Certificate (valid for 10 years, after the entire chain of trust expires)
openssl req -config $CA_CNF -new -x509 -sha256 -days 3650 -extensions v3_ca \
-subj "/C=OO/O=ACME/CN=root.${UNIQ_ID_CA}" -set_serial ${SERIAL} \
-key ca_${UNIQ_ID_CA}.keys.pem -out ca_${UNIQ_ID_CA}.crt.pem
# verify certificate (output to text file for review)
openssl x509 -noout -text -in ca_${UNIQ_ID_CA}.crt.pem > ca_${UNIQ_ID_CA}_cert.info.txt
}
#
# Create CA Intermediate
#
#
# This function will generate a CA Intermediate
# IN: UNIQ_ID_CA, SERIAL
#
generate_ca_i() {
echo_block "Create CA Intermediate (${UNIQ_ID_CA})"
# params
UNIQ_ID_CA=$1
SERIAL=$2
openssl genrsa -out "ca_i_${UNIQ_ID_CA}.keys.pem" 4096
# Create Cert Signing Request (CSR)
openssl req -config $CA_CNF -new -sha256 \
-subj "/C=OO/O=ACME/OU=ACME Intermediate/CN=${UNIQ_ID_CA}" \
-key "ca_i_${UNIQ_ID_CA}.keys.pem" -out "ca_i_${UNIQ_ID_CA}.csr.pem"
# Create Certificate (valid for ~2 years, after the entire chain of trust expires)
# CA signs Intermediate
openssl x509 -req -days 750 -extfile $CA_CNF -extensions v3_ca_i \
-CA $FQ_CA_CERT -CAkey $FQ_CA_KEYS -set_serial ${SERIAL} \
-in "ca_i_${UNIQ_ID_CA}.csr.pem" -out "ca_i_${UNIQ_ID_CA}.crt.pem"
# Package the Certificate Authority Certificates for distro (windoze needs this)
openssl pkcs12 -export -password "pass:password" -inkey "ca_i_${UNIQ_ID_CA}.keys.pem" \
-name "CA Intermediate Mobile Provision" -certfile $FQ_CA_CERT \
-in "ca_i_${UNIQ_ID_CA}.crt.pem" -out "ca_i_${UNIQ_ID_CA}.p12"
# verify certificate (output to text file for review)
openssl x509 -noout -text -in "ca_i_${UNIQ_ID_CA}.crt.pem" > "ca_i_${UNIQ_ID_CA}_crt_info.txt"
# create certifiate chain
cat $FQ_CA_CERT "ca_i_${UNIQ_ID_CA}.crt.pem" > "ca_cert-chain_${UNIQ_ID_CA}.crts.pem"
}
#
# Generate a Server Certificate
# IN: UNIQ_ID, UNIQ_ID_CA, SERIAL
#
generate_server() {
echo_block "Generate Server Certificates (${UNIQ_ID})"
# params
UNIQ_ID=$1
UNIQ_ID_CA=$2
SERIAL=$3
openssl genrsa -out "server_${UNIQ_ID}.keys.pem" 4096
openssl req -new -config $FQ_S_CNF -key "server_${UNIQ_ID}.keys.pem" \
-subj "/C=OO/O=ACME/OU=ACME Standard/CN=${UNIQ_ID}" \
-out "server_${UNIQ_ID}.csr.pem"
# Intermediate signs Server
openssl x509 -req -days 365 -extfile $FQ_S_CNF -extensions v3_server \
-CA "ca_i_${UNIQ_ID_CA}.crt.pem" -CAkey "ca_i_${UNIQ_ID_CA}.keys.pem" -set_serial ${SERIAL} \
-in "server_${UNIQ_ID}.csr.pem" -out "server_${UNIQ_ID}.crt.pem"
# Package the Certificates
openssl pkcs12 -export -password "pass:password" -inkey "server_${UNIQ_ID}.keys.pem" \
-name "Server ${UNIQ_ID} VPN Certificate" -certfile "ca_cert-chain_${UNIQ_ID_CA}.crts.pem" -caname "server_${UNIQ_ID}@acme.xyz" \
-in "server_${UNIQ_ID}.crt.pem" -out "server_${UNIQ_ID}.p12"
# verify certificate (output to text file for review)
openssl x509 -noout -text -in "server_${UNIQ_ID}.crt.pem" > "server_${UNIQ_ID}.crt.info.txt"
}
#
# Generate a Client Certificate
# IN: UNIQ_ID, UNIQ_ID_CA, SERIAL
#
generate_client() {
echo_block "Generate Client Certificates (${UNIQ_ID})"
# params
UNIQ_ID=$1
UNIQ_ID_CA=$2
SERIAL=$3
openssl genrsa -out "client_${UNIQ_ID}.keys.pem" 4096
openssl req -new -key "client_${UNIQ_ID}.keys.pem" \
-subj "/C=OO/O=ACME/OU=ACME Standard/CN=client_${UNIQ_ID}" \
-out "client_${UNIQ_ID}.csr.pem"
# Intermediate signs Client
openssl x509 -req -days 365 \
-CA "ca_i_${UNIQ_ID_CA}.crt.pem" -CAkey "ca_i_${UNIQ_ID_CA}.keys.pem" -set_serial ${SERIAL} \
-in "client_${UNIQ_ID}.csr.pem" -out "client_${UNIQ_ID}.crt.pem"
# Package the Certificates
openssl pkcs12 -export -password "pass:password" -inkey "client_${UNIQ_ID}.keys.pem" \
-name "Client ${UNIQ_ID} VPN Certificate" -certfile "ca_cert-chain_${UNIQ_ID_CA}.crts.pem" -caname "client_${UNIQ_ID}@acme.xyz" \
-in "client_${UNIQ_ID}.crt.pem" -out "client_${UNIQ_ID}.p12"
# verify certificate (output to text file for review)
openssl x509 -noout -text -in "client_${UNIQ_ID}.crt.pem" > "client_${UNIQ_ID}.info.txt"
}

View File

@ -22,8 +22,8 @@ usage() {
echo echo
echo " usage: gen_ca-i.sh <Org URL> <Serial>" echo " usage: gen_ca-i.sh <Org URL> <Serial>"
echo echo
echo " example: gen_ca-i.sh skunkworks.acme.xyz \\" echo " example: gen_ca-i.sh skunkworks.acme.xyz"
echo " 10052 \\" echo " 10052"
echo echo
exit 1 exit 1
} }
@ -67,9 +67,12 @@ generate_ca_i() {
cat $FQ_CA_CERT "ca_i_${UNIQ_ID_CA}.crt.pem" > "ca_cert-chain_${UNIQ_ID_CA}.crts.pem" cat $FQ_CA_CERT "ca_i_${UNIQ_ID_CA}.crt.pem" > "ca_cert-chain_${UNIQ_ID_CA}.crts.pem"
} }
main() { main() {
if [[ ! -f ca-i.pem ]] if [[ ! -f ca-i.pem ]]; then
error_no_ca_file error_no_ca_file
fi
if [[ -n $PARAM1 ]] || [[ -n $PARAM2 ]]; then if [[ -n $PARAM1 ]] || [[ -n $PARAM2 ]]; then
generate_ca_i $PARAM1 $PARAM2 generate_ca_i $PARAM1 $PARAM2
else else

View File

@ -1,56 +0,0 @@
#
#
# IMPORTANT INFO
#
#
[ v3_server ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "ACME Generated"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = IP:192.168.1.3
#subjectAltName = @san_info
[ san_info ]
IP = 192.168.1.3
#
#
# FORCED TO INCLUDE THIS JUNK
#
#
[ req ]
# Options for the `req` tool (`man req`).
default_bits = 4096
distinguished_name = req_distinguished_name
string_mask = utf8only
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
# Extension to add when the -x509 option is used.
#x509_extensions = v3_ca
[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
0.organizationName = Organization Name
organizationalUnitName = Organizational Unit Name
commonName = Common Name
emailAddress = Email Address
# Optionally, specify some defaults.
countryName_default = US
stateOrProvinceName_default = State51
localityName_default =
0.organizationName_default = ACME R&D
organizationalUnitName_default =
emailAddress_default =

View File

@ -1,113 +0,0 @@
# Root CA configuration file.
[ ca ]
# `man ca`
default_ca = CA_default
[ CA_default ]
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
name_opt = ca_default
cert_opt = ca_default
default_days = 375
preserve = no
policy = policy_strict
[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
# Options for the `req` tool (`man req`).
default_bits = 4096
distinguished_name = req_distinguished_name
string_mask = utf8only
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
# Extension to add when the -x509 option is used.
x509_extensions = v3_ca
[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
0.organizationName = Organization Name
organizationalUnitName = Organizational Unit Name
commonName = Common Name
emailAddress = Email Address
# Optionally, specify some defaults.
countryName_default = US
stateOrProvinceName_default = State51
localityName_default =
0.organizationName_default = ACME R&D
organizationalUnitName_default =
emailAddress_default =
[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
basicConstraints = critical, CA:true
keyUsage = critical, cRLSign, digitalSignature, keyCertSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
[ v3_ca_i ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, cRLSign, digitalSignature, keyCertSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "ACME Generated"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection
[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "ACME Generated"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
#subjectAltName = "192.168.123.129"
[ crl_ext ]
# Extension for CRLs (`man x509v3_config`).
authorityKeyIdentifier=keyid:always
[ ocsp ]
# Extension for OCSP signing certificates (`man ocsp`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning

View File

@ -1,55 +0,0 @@
#
#
# IMPORTANT INFO
#
#
[ v3_server ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "ACME Corp"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
#subjectAltName = IP:192.168.123.129
[ alt_names ]
DNS.1 = "skunkworks.acme.xyz"
#
#
# FORCED TO INCLUDE THIS JUNK
#
#
[ req ]
# Options for the `req` tool (`man req`).
default_bits = 4096
distinguished_name = req_distinguished_name
string_mask = utf8only
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
# Extension to add when the -x509 option is used.
#x509_extensions = v3_ca
[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
0.organizationName = Organization Name
organizationalUnitName = Organizational Unit Name
commonName = Common Name
emailAddress = Email Address
# Optionally, specify some defaults.
countryName_default = US
stateOrProvinceName_default = State51
localityName_default =
0.organizationName_default = ACME R&D
organizationalUnitName_default =
emailAddress_default =

View File

@ -1,116 +0,0 @@
#!/bin/bash
#
# ACME Certificate Authority Generation v1.0
#
#
PARAM1=$1
usage() {
echo
echo "This script will generate all the files necessary to build a certificate chain of trust"
echo "using a CA, CA Intermediate, Server, and Client certificates. After the bootstrap the other"
echo "helper scripts will generate new certificates"
echo
echo "Usage: cert_bootstrap <.cnf file (minus the .cnf)>"
echo
echo "Example: cert_bootstrap org.acme.xyz"
exit 1
}
echo_block() {
echo
echo
echo "***** ***** ***** *****"
echo $1
echo "***** ***** ***** *****"
}
#
# CA generation requires .cnf files
# create CA directory
# create bash variables to CA
# restore script back to original path
#
app_init() {
if [[ -n $PARAM1 ]]; then
# need to know the location of the configuration file (expected to be in same dir path as this script)
CA_CNF="$CD/ca.cnf"
# handle the case of having the ".cnf" extension or not
if [[ ${PARAM1: -4} == .cnf ]]; then
ORG_URL=${PARAM1%.*}
S_CNF=${PARAM1}
echo "ASDF: ${ORG_URL}, ${S_CNF}"
else
ORG_URL=$PARAM1
S_CNF="${PARAM1}.cnf"
echo "ZXCV: ${ORG_URL}, ${S_CNF}"
fi
FQ_S_CNF="${CD}/${S_CNF}"
if [[ ! -f $FQ_S_CNF ]] || [[ ! -f $CA_CNF ]]; then
usage
fi
else
usage
fi
# Organize
#
# create a unique path for the server certificate
UNIQ_DIR=`date +%Y-%m-%d.%H_%M_%S`
UNIQ_DIR="cert-chain_${UNIQ_DIR}"
mkdir -p "${UNIQ_DIR}"
cd "${UNIQ_DIR}"
# FQ_DIR="${CD}/${UNIQ_DIR}"
}
#
# IN: UNIQ_ID_CA, SERIAL
#
one-time-ca() {
# params
SERIAL="101"
UNIQ_ID_CA="${SERIAL}.${ORG_URL}"
CA_DIR="ca_${UNIQ_ID_CA}"
mkdir $CA_DIR
cd $CA_DIR
generate_ca $UNIQ_ID_CA $SERIAL
FQ_CA_DIR=`pwd`
FQ_CA_CERT="${FQ_CA_DIR}/ca_${UNIQ_ID_CA}.crt.pem"
FQ_CA_KEYS="${FQ_CA_DIR}/ca_${UNIQ_ID_CA}.keys.pem"
cd ..
}
# ***** ***** ***** *****
#
# CERTIFICATE AUTHORITY
#
# ***** ***** ***** *****
# This function will generate a CA Intermediate
# IN: UNIQ_ID_CA, SERIAL
#
generate_ca() {
# params
UNIQ_ID_CA=$1
SERIAL=$2
# encrypt the key
#openssl genrsa -aes256 -out ca.keys.pem 4096
#openssl genrsa -aes256 -password "pass:password" -out ca.keys.pem 4096
# key un-protected
openssl genrsa -out "ca_${UNIQ_ID_CA}.keys.pem" 4096
#
# Create Certificate (valid for 10 years, after the entire chain of trust expires)
openssl req -config $CA_CNF -new -x509 -sha256 -days 3650 -extensions v3_ca \
-subj "/C=OO/O=ACME/CN=root.${UNIQ_ID_CA}" -set_serial ${SERIAL} \
-key ca_${UNIQ_ID_CA}.keys.pem -out ca_${UNIQ_ID_CA}.crt.pem
# verify certificate (output to text file for review)
openssl x509 -noout -text -in ca_${UNIQ_ID_CA}.crt.pem > ca_${UNIQ_ID_CA}_cert.info.txt
}
main() {
}