You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
3.7 KiB
155 lines
3.7 KiB
#!/bin/bash
|
|
|
|
#:-
|
|
. /etc/shlib
|
|
#:-
|
|
|
|
include common
|
|
include pretty
|
|
|
|
usage="$exname [--server] [--altname ALTNAME] [--days DAYS] COMMONNAME EMAIL"
|
|
|
|
|
|
. /etc/default/ca
|
|
|
|
CA_PASSWORD_FILE=${CA_PASSWORD_FILE:-$CA_CONFIG/password}
|
|
|
|
if ! [ -e "$CA_PASSWORD_FILE" ]; then
|
|
die "Password file '$CA_PASSWORD_FILE' does not exist. Either create it or set \$CA_PASSWORD_FILE."
|
|
fi
|
|
|
|
|
|
##
|
|
## Arguments
|
|
##
|
|
|
|
server_cert=
|
|
altnames=()
|
|
while [ "$1" ]; do
|
|
case "$1" in
|
|
"--server")
|
|
server_cert=true
|
|
;;
|
|
"--altname="*)
|
|
altnames=(${altnames[@]} ${1#--altname=})
|
|
;;
|
|
"--altname")
|
|
altnames=(${altnames[@]} $2)
|
|
shift
|
|
;;
|
|
"--days="*)
|
|
DAYS="${1#--altname=}"
|
|
;;
|
|
"--days")
|
|
DAYS="${2}"
|
|
shift
|
|
;;
|
|
*)
|
|
[ -z ${common_name+x} ] && { common_name=$1 ; shift; continue; }
|
|
[ -z ${email+x} ] && { email=$1 ; shift; continue; }
|
|
die "Unexpected argument '$1'."
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
if [ -z "${common_name+x}" ] || [ -z "${email+x}" ]; then
|
|
err "Missing mandatory positional argument."
|
|
print_usage
|
|
exit 1
|
|
fi
|
|
|
|
for i in COUNTRY STATE ORGANISATION DAYS; do
|
|
if [ -z "${!i}" ]; then
|
|
die "Missing/Empty variable '$i'. You can add it to \`/etc/default/ca\`."
|
|
fi
|
|
done
|
|
|
|
keyfile="$CA_DATA/keys/$common_name"
|
|
|
|
if [ -e "$keyfile.crt+key" ]; then
|
|
warn "Keyfile '$keyfile.crt+key' already exist."
|
|
exit 0
|
|
fi
|
|
|
|
tmpdir=$(mktemp -d)
|
|
trap 'rm -rf "$tmpdir"' EXIT
|
|
|
|
|
|
##
|
|
## Subject building
|
|
##
|
|
|
|
subject=()
|
|
[ -z "${COUNTRY+x}" ] || subject=("${subject[@]}" "C=$COUNTRY")
|
|
[ -z "${STATE+x}" ] || subject=("${subject[@]}" "ST=$STATE")
|
|
[ -z "${ORGANISATION+x}" ] || subject=("${subject[@]}" "O=$ORGANISATION")
|
|
subject=("${subject[@]}" "CN=$common_name")
|
|
subject=("${subject[@]}" "emailAddress=$email")
|
|
|
|
SUBJECT=$(for elt in "${subject[@]}"; do echo -n "/$elt"; done)
|
|
|
|
|
|
##
|
|
## Openssl Options
|
|
##
|
|
|
|
openssl_opts=()
|
|
openssl_req_opts=()
|
|
openssl_ca_opts=()
|
|
[ -z "${DAYS+x}" ] && openssl_opts=("${openssl_opts[@]}" "-days" "$DAYS")
|
|
|
|
|
|
if [ "$server_cert" ]; then
|
|
if ! egrep "^#\s*nsCertType\s*=\s*server\s*$" "/etc/ssl/openssl.cnf" > /dev/null 2>&1; then
|
|
err "Unexistent line about 'nsCertType' in '/etc/ssl/openssl.cnf' reference."
|
|
die "Can't activate the server certificate."
|
|
fi
|
|
[ -e "$tmpdir/openssl.cnf" ] || cp /etc/ssl/openssl.cnf "$tmpdir/openssl.cnf"
|
|
sed -ri 's/^#\s*(nsCertType\s*=\s*server\s*)$/\1/g' "$tmpdir/openssl.cnf"
|
|
new_openssl_cnf=true
|
|
fi
|
|
|
|
if [ "${altnames[*]}" ]; then
|
|
[ -e "$tmpdir/openssl.cnf" ] || cp /etc/ssl/openssl.cnf "$tmpdir/openssl.cnf"
|
|
openssl_req_opts=("${openssl_req_opts[@]}" "-reqexts" SAN)
|
|
openssl_ca_opts=("${openssl_ca_opts[@]}" "-extensions" SAN)
|
|
cat <<EOF >> "$tmpdir/openssl.cnf"
|
|
[SAN]
|
|
subjectAltName = $(for altname in "${altnames[@]}"; do echo -n "DNS:$altname,"; done | rev | cut -c 2- | rev)
|
|
EOF
|
|
new_openssl_cnf=true
|
|
fi
|
|
|
|
[ "$new_openssl_cnf" ] && openssl_opts=("${openssl_opts[@]}" "-config" "$tmpdir/openssl.cnf")
|
|
|
|
|
|
##
|
|
## Okay, lets do the real work
|
|
##
|
|
|
|
cd "$tmpdir"
|
|
|
|
Wrap -q -d "Generating request" <<EOF || exit 1
|
|
openssl req -new -nodes \
|
|
-keyout "$tmpdir/newkey.pem" \
|
|
-out "$tmpdir/newreq.pem" \
|
|
-subj "$SUBJECT" \
|
|
${openssl_opts[@]} \
|
|
${openssl_req_opts[@]}
|
|
|
|
EOF
|
|
|
|
Wrap -q -d "Signing request" <<EOF || exit 1
|
|
openssl ca -batch \
|
|
-policy policy_anything \
|
|
-out "$tmpdir/newcert.pem" \
|
|
-passin file:"$CA_PASSWORD_FILE" \
|
|
${openssl_opts[@]} \
|
|
${openssl_ca_opts[@]} \
|
|
-infiles "$tmpdir/newreq.pem"
|
|
EOF
|
|
|
|
mv newcert.pem "$keyfile.crt"
|
|
mv newkey.pem "$keyfile.key"
|
|
cat "$keyfile.crt" "$keyfile.key" > "$keyfile.crt+key"
|