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

Sign csr and add initial ssh management #6

Open
wants to merge 8 commits into
base: develop
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
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ before_install:
script:
- |
bash --posix ./create-root-ca -l -d travis-ca <<EOF
n
travis-ca
bogus.com
US
Expand All @@ -28,13 +29,15 @@ script:
rootCA_password
San Francisco
Jurisdiction of travis-server.bogus-com
n
EOF
- |
bash --posix ./bin/create-client -c travis-client << EOF
rootCA_password
San Francisco
private
travis-client@bogus.com
n
EOF
- |
bash --posix ./bin/revoke-cert -c certs/server/travis-server-bogus-com/travis-server-bogus-com.crt << EOF
Expand All @@ -45,6 +48,7 @@ script:
- |
bash --posix ./bin/create-signing-ca -d travis-signing << EOF
rootCA_password
n
travis-signing
bogus.com
US
Expand All @@ -64,13 +68,15 @@ script:
signCA_password
San Francisco
Jurisdiction of travis-server.bogus-com
n
EOF
- |
bash --posix ./bin/create-client -c travis-client << EOF
signCA_password
San Francisco
private
travis-client@bogus.com
n
EOF
- |
bash --posix ./bin/revoke-cert -c certs/server/travis-server-bogus-com/travis-server-bogus-com.crt << EOF
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ A suite of bash scripts for automating very basic OpenSSL Certificate Authority
* Creating Server certificates
* Creating Client certificates
* Revoking certificates and maintaining CRLs
* Creating CSRs
* Managing SSH keys

## Usage

Expand All @@ -27,6 +29,7 @@ A suite of bash scripts for automating very basic OpenSSL Certificate Authority
| revoke-cert | Revoke a (client\|server) certificate |
| show-status | Show the infos about the current CA (signed certificates...) |
| sign-csr | Sign an imported client certificate |
| create-csr | Create a client certificate |

#### Important files:

Expand All @@ -49,6 +52,8 @@ create-root-ca -d $ROOT_CA_DIR

```
$ROOT_CA_DIR/ca/ca.crt
$ROOT_CA_DIR/ca/ca.pub
$ROOT_CA_DIR/ca/ca.ssh.pub
$ROOT_CA_DIR/ca/private/ca.key
$ROOT_CA_DIR/ca/ca.crl
```
Expand All @@ -65,6 +70,8 @@ $ROOT_CA_DIR/bin/create-signing-ca -d $SIGNING_CA_DIR

```
$SIGNING_CA_DIR/ca/ca.crt
$SIGNING_CA_DIR/ca/ca.pub
$SIGNING_CA_DIR/ca/ca.ssh.pub
$SIGNING_CA_DIR/ca/private/ca.key
$SIGNING_CA_DIR/ca/ca.crl
$SIGNING_CA_DIR/ca/root.crt
Expand All @@ -86,6 +93,8 @@ All addresses **must** be supplied via the *-a* flag.
```
$CA_DIR/certs/server/FQDN-Description/FQDN-Description.crt
$CA_DIR/certs/server/FQDN-Description/FQDN-Description.key
$CA_DIR/certs/server/FQDN-Description/FQDN-Description.pub
$CA_DIR/certs/server/FQDN-Description/FQDN-Description.ssh.pub
$CA_DIR/certs/server/FQDN-Description/FQDN-Description.csr
```

Expand All @@ -102,6 +111,8 @@ $CA_DIR/bin/create-client -c user@domain.com
```
$CA_DIR/certs/clients/user-domain-com/user-domain-com.crt
$CA_DIR/certs/clients/user-domain-com/user-domain-com.key
$CA_DIR/certs/clients/user-domain-com/user-domain-com.pub
$CA_DIR/certs/clients/user-domain-com/user-domain-com.ssh.pub
$CA_DIR/certs/clients/user-domain-com/user-domain-com.csr
```

Expand Down Expand Up @@ -130,6 +141,7 @@ These scripts are very simple, and make some hard-coded assumptions about behavi
* Client and Server certificates have 3072-bit RSA keys (configurable in *defaults.conf*)
* Client and Server keys are not encrypted
* There is no wrapper *yet* for renewing certificates
* PKCS11 support is in beta

## License

Expand Down
83 changes: 70 additions & 13 deletions create-client
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

# Derek Moore <derek.moore@gmail.com>
# Christian Göttsche <cgzones@googlemail.com>
# Tom Bereknyei <tomberek@gmail.com>

set -eu
set -o pipefail
Expand Down Expand Up @@ -59,14 +60,23 @@ fi


echo
if [ -n "$CA_ENABLE_ENGINE" ]; then
echo -e "$NOTE Your CA key is on PKCS11 device, enter PIN."
fi
echo -e -n "$INPUT Enter passphase for signing CA key: "
read -r -s PASS
echo
export CA_PASS="${PASS}"
openssl rsa -check \
-in ca/private/ca.key \
-passin env:CA_PASS \
-noout

openssl_engine_cmd='
-engine pkcs11
-inform engine
-in pkcs11:object=SIGN%20key'
openssl rsa \
${CA_ENABLE_ENGINE:+$openssl_engine_cmd} \
$( [ -z $CA_ENABLE_ENGINE ] && echo "-check -in ca/private/ca.key") \
-noout \
-passin env:CA_PASS

trap 'rm -Rf "certs/clients/$SAFE_NAME"' 0
mkdir "certs/clients/$SAFE_NAME"
Expand All @@ -76,32 +86,79 @@ export CA_USERNAME="${CLIENT_NAME}"
export CA_CERT_MAIL=""
ask_client_cert_questions
export SAN="email:$CA_CERT_MAIL"
template "${BIN_DIR}/templates/client.tpl" "certs/clients/$SAFE_NAME/$SAFE_NAME.conf"
template "${BIN_DIR}/templates/clients.tpl" "certs/clients/$SAFE_NAME/$SAFE_NAME.conf"

echo -e -n "$INPUT Create csr on pkcs11 device? (key must be in \"PIV AUTH key\" or 9a): [yN]"
read -r SURE
if [ "${SURE}" != "y" ] && [ "${SURE}" != "Y" ]; then
ENABLE_ENGINE=
else
ENABLE_ENGINE=1
init_slot 9a "certs/clients/$SAFE_NAME/$SAFE_NAME.pub"
fi

echo -e "$NOTE Creating the client key and csr"

# Create the client key and csr
openssl req -new -nodes \
-batch \
openssl_engine_cmd='
-engine pkcs11
-keyform engine
-key pkcs11:object=PIV%20AUTH%20key'
openssl req -new -batch \
${ENABLE_ENGINE:+$openssl_engine_cmd} \
-config "certs/clients/$SAFE_NAME/$SAFE_NAME.conf" \
-keyout "certs/clients/$SAFE_NAME/$SAFE_NAME.key" \
-out "certs/clients/$SAFE_NAME/$SAFE_NAME.csr"
openssl rsa -noout -check -in "certs/clients/$SAFE_NAME/$SAFE_NAME.key"
chmod 0400 "certs/clients/$SAFE_NAME/$SAFE_NAME.key"
-out "certs/clients/$SAFE_NAME/$SAFE_NAME.csr" \
$( [ -z $ENABLE_ENGINE ] && echo "
-nodes
-keyout certs/clients/$SAFE_NAME/$SAFE_NAME.key")

openssl_engine_cmd='
-engine pkcs11
-inform engine
-in pkcs11:object=PIV%20AUTH%20key'
openssl rsa \
${ENABLE_ENGINE:+$openssl_engine_cmd} \
$( [ -z $ENABLE_ENGINE ] && echo "-check -in certs/clients/$SAFE_NAME/$SAFE_NAME.key") \
-noout

if [ -z "$ENABLE_ENGINE" ]; then
chmod 0400 "certs/clients/$SAFE_NAME/$SAFE_NAME.key"
openssl rsa -in "certs/clients/$SAFE_NAME/$SAFE_NAME.key" \
-pubout -out "certs/clients/$SAFE_NAME/$SAFE_NAME.pub"
fi
ssh-keygen -f "certs/clients/$SAFE_NAME/$SAFE_NAME.pub" -i -mPKCS8 \
| awk "{printf \$0;print \" ${SAFE_NAME}\"}" > "certs/clients/$SAFE_NAME/$SAFE_NAME.ssh.pub"

echo -e "$NOTE Creating the client certificate"

# Create the client certificate
openssl_engine_cmd="\
-engine pkcs11 \
-keyform engine \
-keyfile pkcs11:object=SIGN%20key"
openssl ca -batch -notext \
${CA_ENABLE_ENGINE:+$openssl_engine_cmd} \
-config ca/ca.conf \
-in "certs/clients/$SAFE_NAME/$SAFE_NAME.csr" \
-out "certs/clients/$SAFE_NAME/$SAFE_NAME.crt" \
-extensions client_ext \
-extensions clients_ext \
-passin env:CA_PASS

if [[ -n "$ENABLE_ENGINE" ]]; then
replace_crt 9a certs/clients/"$SAFE_NAME"/"$SAFE_NAME".crt
fi

echo -e "$NOTE Verifying certificate/key pair"

key_mod=$(openssl rsa -noout -modulus -in "certs/clients/$SAFE_NAME/$SAFE_NAME.key")
openssl_engine_cmd="\
-engine pkcs11 \
-inform engine \
-in pkcs11:object=PIV%20AUTH%20key"
key_mod=$(openssl rsa \
${ENABLE_ENGINE:+$openssl_engine_cmd} -noout -modulus \
$( [ -z $ENABLE_ENGINE ] && echo "-in certs/clients/$SAFE_NAME/$SAFE_NAME.key")
)

cert_mod=$(openssl x509 -noout -modulus -in "certs/clients/$SAFE_NAME/$SAFE_NAME.crt")

if [ ! "$key_mod" = "$cert_mod" ];then
Expand Down
159 changes: 159 additions & 0 deletions create-csr
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
#!/bin/bash

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

# Derek Moore <derek.moore@gmail.com>
# Christian Göttsche <cgzones@googlemail.com>
# Tom Bereknyei <tomberek@gmail.com>

set -eu
set -o pipefail

umask 0077

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

usage() {
echo "Usage: $0 -c CSR_PATH [-F NAME] [-s] [-m CSR_CERT_MAIL]"
echo "Create a client certificate request located at CSR_PATH"
echo
echo "Options:"
echo " -c CSR_NAME Name of certificate request"
echo
echo " -s Request is a server [default is client]"
echo
echo " -k KEY_PATH Path to key to use [default is to create one]"
echo
echo " -m CSR_CERT_MAIL Email address to use in client certificate request"
echo " Useful when using ykman which doesn't use email"
echo
echo " -F NAME Force to use custom SAFE_NAME"
echo " Useful for name clahses, use with caution"
echo
}

if [ ! -f ca/ca.crt ]; then
echo -e "$ERR Must be run inside a CA directory!"
exit 2
fi

CSR_PATH=
CSR_NAME=
CSR_TYPE="clients"
CSR_KEY=
CSR_CERT_MAIL=

while getopts c:sk:F:m:h FLAG; do
case $FLAG in
c) CSR_PATH=${OPTARG} ;;
F) CSR_NAME=${OPTARG} ;;
m) CSR_CERT_MAIL=${OPTARG} ;;
s) CSR_TYPE="server" ;;
k) CSR_KEY=${OPTARG} ;;
h) echo -e -n "$SUCC " && usage && exit 0 ;;
*) echo -e -n "$ERR " && usage && exit 2 ;;
esac
done

if [ $OPTIND -le $# ]; then
echo -e -n "$ERR " && usage && exit 2
elif [ "$CSR_PATH" = "" ]; then
echo -e -n "$ERR " && usage && exit 1
fi

if [ -n "$CSR_NAME" ]; then
SAFE_NAME=$(echo "$CSR_NAME" | sed 's/\*/star/g' | sed 's/[^A-Za-z0-9-]/-/g')
else
SAFE_NAME=$(echo "$CSR_PATH" | sed 's/\*/star/g' | sed 's/[^A-Za-z0-9-]/-/g')
fi

echo -e "$NOTE Creating new "$CSR_TYPE" certificate request for '$SAFE_NAME'"

if [ -f "certs/$CSR_TYPE/$SAFE_NAME/$SAFE_NAME.crt" ]; then
echo -e "$ERR Certificate already exist for ($CSR_TYPE/$SAFE_NAME), exiting."
exit 1
fi

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

mkdir -p "certs/$CSR_TYPE/$SAFE_NAME"

# Generate the client cert openssl config
export CA_USERNAME="${SAFE_NAME}"
export CA_CERT_MAIL="${CSR_CERT_MAIL}"
if [[ "$CSR_TYPE" = "server" ]]; then
ask_server_cert_questions
else
ask_client_cert_questions
fi
export SAN="email:$CA_CERT_MAIL"
template "${BIN_DIR}/templates/$CSR_TYPE.tpl" "certs/$CSR_TYPE/$SAFE_NAME/$SAFE_NAME.conf"

echo -e "$NOTE Key is ${CSR_KEY:-" being created"}"

ENABLE_ENGINE=
if [[ -z "$CSR_KEY" ]]; then
echo -e -n "$INPUT Use PKCS11 Engine for this csr (key must be in \"PIV AUTH key\" or 9a)? [y/N]: "
read -r ENABLE_ENGINE
if [ "${ENABLE_ENGINE}" == "y" ] || [ "${ENABLE_ENGINE}" == "Y" ]; then
ENABLE_ENGINE=1
init_slot 9a "certs/$CSR_TYPE/$SAFE_NAME/$SAFE_NAME.pub"
else
ENABLE_ENGINE=
fi
else
cp "$CSR_KEY" "certs/$CSR_TYPE/$SAFE_NAME/$SAFE_NAME.key"
chmod 0400 "certs/$CSR_TYPE/$SAFE_NAME/$SAFE_NAME.key"
openssl rsa -in "certs/$CSR_TYPE/$SAFE_NAME/$SAFE_NAME.key" \
-pubout -out "certs/$CSR_TYPE/$SAFE_NAME/$SAFE_NAME.pub"
fi

echo -e "$NOTE Creating csr"

# Create the csr
openssl_engine_cmd='
-engine pkcs11
-keyform engine
-key pkcs11:object=PIV%20AUTH%20key'
openssl req -new -batch \
${ENABLE_ENGINE:+$openssl_engine_cmd} \
-config "certs/$CSR_TYPE/$SAFE_NAME/$SAFE_NAME.conf" \
-out "certs/$CSR_TYPE/$SAFE_NAME/$SAFE_NAME.csr" \
$( [ -z $ENABLE_ENGINE ] && echo "
-nodes
${CSR_KEY:+"-key $CSR_KEY"}
$( [ -z $CSR_KEY ] && echo "-keyout certs/$CSR_TYPE/$SAFE_NAME/$SAFE_NAME.key")
")

openssl_engine_cmd='
-engine pkcs11
-inform engine
-in pkcs11:object=PIV%20AUTH%20key'
openssl rsa \
${ENABLE_ENGINE:+$openssl_engine_cmd} \
$( [ -z $ENABLE_ENGINE ] && echo "-check -in certs/$CSR_TYPE/$SAFE_NAME/$SAFE_NAME.key") \
-noout

echo values $ENABLE_ENGINE $CSR_KEY
if [ -z "$ENABLE_ENGINE" ] && [ -z "$CSR_KEY" ]; then
echo entered
pwd
chmod 0400 "certs/$CSR_TYPE/$SAFE_NAME/$SAFE_NAME.key"
openssl rsa -in "certs/$CSR_TYPE/$SAFE_NAME/$SAFE_NAME.key" \
-pubout -out "certs/$CSR_TYPE/$SAFE_NAME/$SAFE_NAME.pub"
fi

ssh-keygen -f "certs/$CSR_TYPE/$SAFE_NAME/$SAFE_NAME.pub" -i -mPKCS8 \
| awk "{printf \$0;print \" ${SAFE_NAME}\"}" > "certs/$CSR_TYPE/$SAFE_NAME/$SAFE_NAME.ssh.pub"

echo -e "$NOTE Verifying csr"

openssl req -text -noout -verify -in "certs/$CSR_TYPE/$SAFE_NAME/$SAFE_NAME.csr"

popd > /dev/null

echo -e "$SUCC CSR for '$SAFE_NAME' created."
Loading