Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to allow automated mode and split of server, clinet and server… #4

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*.one_line
*/*
!conf/*
!templates/*
!.*
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
ORIGINAL project page: https://github.com/redredgroovy/easy-ca

# easy-ca
OpenSSL wrapper scripts for managing basic CA functions

Expand Down Expand Up @@ -110,13 +112,11 @@ $CA_DIR/crl/ca.crl
## Caveats

These scripts are very simple, and make some hard-coded assumptions about behavior and configuration:
* Root and Intermediate CAs have a 3652-day lifetime
* Root and Intermediate CAs have 4096-bit RSA keys
* Root and Intermediate CAs have a 7300-day lifetime
* Root and Intermediate CAs have 8192-bit RSA keys
* Root and Intermediate CA keys are always encrypted
* Only one level of Intermediate CA is supported
* Client and Server certificates have a 730-day lifetime
* Client and Server certificates have 2048-bit RSA keys
* Client and Server certificates have a 3650-day lifetime
* Client and Server certificates have 4096-bit RSA keys
* Client and Server keys are never encrypted
* There is no wrapper for renewing certificates


71 changes: 48 additions & 23 deletions create-client
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,30 @@
# Derek Moore <[email protected]>

usage() {
echo "Usage: $0 -c CLIENT_NAME"
echo "Usage: $0 -c CLIENT_NAME [-A]"
echo "Issues a client certificate for CLIENT_NAME"
echo
echo "Options:"
echo " -c CLIENT_NAME Client name (commonName) for the new cert"
echo " -A Automateion mode, password read from env_variable EASY_CA_PASS"
echo
exit 2
}

CLIENT_NAME=
AUTOMODE=false
OPENSSH_ADDITIONAL_PARAMETERS=""

while getopts c: FLAG; do
while getopts Ac: FLAG; do
case $FLAG in
c) CLIENT_NAME=${OPTARG} ;;
A) AUTOMODE=true ;;
*) usage ;;
esac
done

if [ "${CLIENT_NAME}" == "" ]; then
echo "ERROR: Client name empty"
usage
fi

Expand All @@ -37,36 +42,56 @@ echo

pushd ${BIN_DIR}/.. > /dev/null

if [ -f conf/${SAFE_NAME}.client.conf ]; then
echo "Configuration already exists for '${CLIENT_NAME}', exiting."
exit 1
if [ "${AUTOMODE}" = true ] ; then
if [ -z "${EASY_CA_PASS}" ] ; then
echo "ERROR: Automode set but no (or empty) password provided"
exit 1
else
export OPENSSH_ADDITIONAL_PARAMETERS="-batch"
export CA_PASS=${EASY_CA_PASS}
fi
else
echo -n "Enter passphase for signing CA key: "
read -s PASS
echo
export CA_PASS=${PASS}
fi

echo -n "Enter passphase for signing CA key: "
read -s PASS
echo
export CA_PASS=${PASS}

# Generate the client cert openssl config
export SAN=""
export CA_USERNAME=${CLIENT_NAME}
template "${BIN_DIR}/templates/client.tpl" "conf/${SAFE_NAME}.client.conf"
if [ -f conf/${SAFE_NAME}.client.conf ]; then
echo "WARNING: Configuration already exists for '${CLIENT_NAME}'"
else
template "${BIN_DIR}/templates/client.tpl" "conf/${SAFE_NAME}.client.conf"
echo "Template conf/${SAFE_NAME}.client.conf created "
fi

# Create the client key and csr
openssl req -new -nodes \
-config conf/${SAFE_NAME}.client.conf \
-keyout private/${SAFE_NAME}.client.key \
-out csr/${SAFE_NAME}.client.csr
chmod 0400 private/${SAFE_NAME}.client.key
if [ -f csr/${SAFE_NAME}.client.csr ]; then
echo "WARNING: CSR already exists for ${SAFE_NAME}."
else
openssl req -new -nodes ${OPENSSH_ADDITIONAL_PARAMETERS} \
-config conf/${SAFE_NAME}.client.conf \
-keyout private/${SAFE_NAME}.client.key \
-out csr/${SAFE_NAME}.client.csr
chmod 0400 private/${SAFE_NAME}.client.key
echo "Client CSR created csr/${SAFE_NAME}.client.csr"
fi

# Create the client certificate
openssl ca -batch -notext \
-config conf/ca.conf \
-in csr/${SAFE_NAME}.client.csr \
-out certs/${SAFE_NAME}.client.crt \
-days 730 \
-extensions client_ext \
-passin env:CA_PASS
if [ -f certs/${SAFE_NAME}.client.crt ]; then
echo "WARNING: CRT already exists for ${SAFE_NAME}"
else
openssl ca -batch -notext \
-config conf/ca.conf \
-in csr/${SAFE_NAME}.client.csr \
-out certs/${SAFE_NAME}.client.crt \
-days 3650 \
-extensions client_ext \
-passin env:CA_PASS
echo "Client CRT created certs/${SAFE_NAME}.client.crt"
fi

popd > /dev/null

Expand Down
131 changes: 131 additions & 0 deletions create-one_liner
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#!/bin/bash

usage() {
echo "Usage: $0 -R"
echo "Usage: $0 [-I] -s SERVER_NAME -t TYPE..."
echo "Usage: $0 -{F|f} <file name>"
echo "Creates one-liner suitable to be copied into various configuration files"
echo
echo "Options:"
echo " -s SERVER_NAME Server hostname (commonName) for the new cert"
echo " -t TYPE This can be server/client/server_client and must match the previously generated certificate"
echo " -R Creates root certificate one-liner"
echo " -I Invert order of certificate and private key in one-liner"
echo " -v Create separate vault"
echo " -F Creates one-liner from one given file and writes output to file .one_liner"
echo " -f Creates one-liner from one given file and writes output to the screen"
echo
exit 2
}

SERVER_NAME=
TYPE=
ROOT=false
INVERTED=false
VAULT=false
DIRECT_FILE_INPUT=
SCREEN_FILE_INPUT=

while getopts vRIF:s:f:t: FLAG; do
case $FLAG in
s) SERVER_NAME=${OPTARG} ;;
t) TYPE=${OPTARG} ;;
v) VAULT=true ;;
R) ROOT=true ;;
I) INVERTED=true ;;
F) DIRECT_FILE_INPUT=${OPTARG} ;;
f) SCREEN_FILE_INPUT=${OPTARG} ;;
*) usage
;;
esac
done

# Special case for processing directly one file
if [[ ${DIRECT_FILE_INPUT} ]] ; then
echo "Checking existence of ${DIRECT_FILE_INPUT}..."
if [ -f ${DIRECT_FILE_INPUT} ] ; then
echo "Creating one liner for ${DIRECT_FILE_INPUT}"
cat ${DIRECT_FILE_INPUT} | sed -E ':a;N;$!ba;s/\r{0,1}\n/\\n/g' > "${DIRECT_FILE_INPUT}.one_liner"
fi
exit 0
fi
if [[ ${SCREEN_FILE_INPUT} ]] ; then
echo "Checking existence of ${SCREEN_FILE_INPUT}..."
if [ -f ${SCREEN_FILE_INPUT} ] ; then
echo "Creating one liner for ${SCREEN_FILE_INPUT}"
cat ${SCREEN_FILE_INPUT} | sed -E ':a;N;$!ba;s/\r{0,1}\n/\\n/g'
fi
exit 0
fi


if [ "${ROOT}" = false ] ; then
if [ "${SERVER_NAME}" == "" ]; then
echo "ERROR: Server name empty"
usage
fi
fi

BIN_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source ${BIN_DIR}/functions
source ${BIN_DIR}/defaults.conf

# Sanitize the commonName to make it suitable for use in filenames
SAFE_NAME=`echo ${SERVER_NAME} | sed 's/\*/star/g'`
SAFE_NAME=`echo ${SAFE_NAME} | sed 's/[^A-Za-z0-9-]/-/g'`

echo
echo "Creating one liner for ${SERVER_NAME}"
echo

pushd ${BIN_DIR}/.. > /dev/null

if [ "${ROOT}" = true ] ; then
# Processing root certificate
if [ -f ca/ca.crt ] ; then
if [ -f one_liner/ca.one_liner ] ; then
echo "ERROR: one_liner/ca.one_liner exists no action taken"
popd > /dev/null
exit 1
else
cat ca/ca.crt | sed -E ':a;N;$!ba;s/\r{0,1}\n/\\n/g' > one_liner/ca.one_liner
echo "One liner one_liner/ca.one_liner created"
fi
else
echo "ERROR: ca/ca.crt did not exists"
popd > /dev/null
exit 1
fi
else
# Processing standard one liner file
if [ -f private/${SAFE_NAME}.${TYPE}.key ] ; then
if [ -f certs/${SAFE_NAME}.${TYPE}.crt ] ; then
if [ "${INVERTED}" = true ] ; then
cat certs/${SAFE_NAME}.${TYPE}.crt private/${SAFE_NAME}.${TYPE}.key | sed -E ':a;N;$!ba;s/\r{0,1}\n/\\n/g' > one_liner/${SAFE_NAME}.${TYPE}.reversed.one_line
else
cat private/${SAFE_NAME}.${TYPE}.key certs/${SAFE_NAME}.${TYPE}.crt | sed -E ':a;N;$!ba;s/\r{0,1}\n/\\n/g' > one_liner/${SAFE_NAME}.${TYPE}.one_line
fi
else
echo "ERROR: certs/${SAFE_NAME}.${TYPE}.crt NOT exists no action taken"
popd > /dev/null
exit 1
fi
else
echo "ERROR: private/${SAFE_NAME}.${TYPE}.key NOT exists no action taken"
popd > /dev/null
exit 1
fi
fi

if [ "${VAULT}" = true ] ; then
if [ -f one_liner/${SAFE_NAME}.${TYPE}.one_line ] ; then
# Creating vault data
cat one_liner/${SAFE_NAME}.${TYPE}.one_line | sed -r 's/(-----BEGIN PRIVATE KEY.*END PRIVATE KEY-----)\\n(-----BEGIN CERTIFICATE.*-----END CERTIFICATE-----)/\{\n "id": "'"${SERVER_NAME}"'",\n "key": "\1",\n "cert": "\2"\n\}/g' > one_liner/${SAFE_NAME}.${TYPE}.vault_separate
fi
fi

popd > /dev/null

echo
echo "one liner created"
echo
45 changes: 29 additions & 16 deletions create-root-ca
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,23 @@
# Derek Moore <[email protected]>

usage() {
echo "Usage: $0 -d CA_DIR"
echo "Usage: $0 -d CA_DIR [-A]"
echo "Initializes a new root CA in CA_DIR"
echo
echo "Options:"
echo " -d CA_DIR Target directory to be created and initialized"
echo " -A Automateion mode, password read from env_variable EASY_CA_PASS"
echo
exit 2
}

CA_DIR=
AUTOMODE=false

while getopts d: FLAG; do
while getopts Ad: FLAG; do
case $FLAG in
d) CA_DIR=${OPTARG} ;;
A) AUTOMODE=true ;;
*) usage ;;
esac
done
Expand All @@ -30,6 +33,7 @@ source ${BIN_DIR}/functions

HOME=$CA_DIR
CA_NAME=$( basename "${HOME}" )
export SAN=""

echo
echo "Creating root CA in '${HOME}'"
Expand All @@ -39,27 +43,36 @@ init_ca_home ${HOME}
generate_conf ${HOME}/bin/defaults.conf
source ${HOME}/bin/defaults.conf

echo
echo -n "Enter passphase for encrypting root CA key: "
read -s PASS1
echo
echo -n "Verifying - Enter passphase for encrypting root CA key: "
read -s PASS2
echo

if [ "${PASS1}" != "${PASS2}" ]; then
echo "Passphrases did not match, exiting."
exit 1
# Get the password
if [ "${AUTOMODE}" = true ] ; then
if [ -z "${EASY_CA_PASS}" ] ; then
echo "ERROR: Automode set but no (or empty) password provided"
exit 1
else
export CA_PASS=${EASY_CA_PASS}
fi
else
echo
echo -n "Enter passphase for encrypting root CA key: "
read -s PASS1
echo
echo -n "Verifying - Enter passphase for encrypting root CA key: "
read -s PASS2
echo
if [ "${PASS1}" != "${PASS2}" ]; then
echo "ERROR: Passphrases did not match, exiting."
exit 1
fi
export CA_PASS=${PASS1}
fi
export CA_PASS=${PASS1}

pushd ${HOME} > /dev/null

# Generate the root CA openssl config
template "${BIN_DIR}/templates/root.tpl" "conf/ca.conf"

# Create the root CA csr
openssl genrsa -out ca/private/ca.key -passout env:CA_PASS 4096
openssl genrsa -out ca/private/ca.key -passout env:CA_PASS 8192
chmod 0400 ca/private/ca.key

# Create the root CA csr
Expand All @@ -74,7 +87,7 @@ openssl ca -selfsign -batch -notext \
-config conf/ca.conf \
-in ca/ca.csr \
-out ca/ca.crt \
-days 3652 \
-days 7300 \
-extensions root_ca_ext \
-passin env:CA_PASS

Expand Down
Loading