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.
 
 
 
 
 
 

218 lines
7.9 KiB

#!/bin/sh
##
## x509-util.sh -- X.509 Certificate Generation Utility
## Copyright (c) 2007-2014 Ralf S. Engelschall <rse@engelschall.com>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
## USA, or contact Ralf S. Engelschall <rse@engelschall.com>.
##
# sane run-time environment
umask 022
# parameter defaults
prefix="@l_prefix@"
tag="snakeoil"
password="snakeoil"
domain="snakeoil.invalid"
organization="Snakeoil Corporation"
lifetime="3650"
num_server="2"
num_client="4"
num_object="4"
tmpdir="${TMPDIR-/tmp}"
outdir="`pwd`"
# parse command line options
while [ $# -gt 0 ]; do
case "$1" in
--prefix=* ) prefix=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;;
--tag=* ) tag=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;;
--password=* ) password=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;;
--domain=* ) domain=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;;
--organization=* ) organization=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;;
--lifetime=* ) lifetime=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;;
--num-server=* ) num_server=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;;
--num-client=* ) num_client=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;;
--num-object=* ) num_object=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;;
--tmpdir=* ) tmpdir=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;;
--outdir=* ) outdir=`echo "$1" | sed -e 's;^--[^=]*=;;'`; shift ;;
--help )
echo "Usage: x509-util [--prefix=<prefix>] [--tag=<tag>] [--password=<password>]"
echo " [--domain=<domain>] [--organization=<organization>] [--lifetime=<lifetime>]"
echo " [--num-server=<num-server>] [--num-client=<num-client>] [--num-object=<num-object>]"
echo " [--tmpdir=<tmpdir>] [--outdir=<outdir>] [--help]"
exit 0
;;
* )
break
;;
esac
done
# display information about parameters
echo "++ generating X.509 certificate/key set with configuration:"
echo "-- OpenPKG prefix (--prefix): $prefix"
echo "-- Short-hand tag (--tag): $tag"
echo "-- Encryption Password (--password): $password"
echo "-- DNS Domain (--domain): $domain"
echo "-- Organization Name (--organization): $organization"
echo "-- Certificate Lifetimes (--lifetime): $lifetime"
echo "-- Number of Server Certificates (--num-server): $num_server"
echo "-- Number of Client Certificates (--num-client): $num_client"
echo "-- Number of Object Certificates (--num-object): $num_object"
echo "-- Temporary Directory (--tmpdir): $tmpdir"
echo "-- Output Directory (--outdir): $outdir"
# sanity check environment
if [ ! -x "$prefix/bin/shtool" ]; then
echo "ERROR: $prefix/bin/shtool (OpenPKG \"shtool\" package) required" 1>&2
exit 1
fi
if [ ! -x "$prefix/bin/csp" ]; then
echo "ERROR: $prefix/bin/csp (OpenPKG \"csp\" package) required" 1>&2
exit 1
fi
if [ ! -x "$prefix/bin/perl" ]; then
echo "ERROR: $prefix/bin/perl (OpenPKG \"perl\" package) required" 1>&2
exit 1
fi
# ensure out directory exists
test -d $outdir || mkdir $outdir 2>/dev/null || true
# create temporary location
echo "++ creating temporary location"
if [ ! -d $tmpdir ]; then
echo "$0: ERROR: temporary directory not existing: $tmpdir" 1>&2
exit 1
fi
tmpdir="$tmpdir/x509-util.$$.tmp"
test -d $tmpdir && rm -rf $tmpdir >/dev/null 2>&1 || true
mkdir $tmpdir || exit $?
cd $tmpdir || exit $?
# display processing information
echo "++ creating CSP environment"
# create CSP environment
rm -rf etc csp
ln -s $prefix/etc/csp etc
mkdir csp
$prefix/bin/csp $tag create
# optionally adjust configuration
$prefix/bin/shtool subst -q \
-e "s;example\\.com;$domain;g" \
csp/$tag/extensions.conf
rm -f csp/$tag/extensions.conf.orig
# display processing information
echo "++ generate CA private key and certificate"
# generate CA private key and certificate
$prefix/bin/csp $tag init \
--keysize=4096 --keypass="$password" --type=ca --days=$lifetime \
"CN=Certificate Authority (CA), OU=Certification Department, O=$organization"
idx=0
# make all files available under common path
echo "-- $tag-ca.key.pem"
cp csp/$tag/private/ca.key $outdir/$tag-ca.key.pem
echo "-- $tag-ca.crt.pem"
cp csp/$tag/ca.crt $outdir/$tag-ca.crt.pem
# provide textual presentations
echo "-- $tag-ca.key.txt"
$prefix/bin/openssl rsa \
-in $outdir/$tag-ca.key.pem -passin "pass:$password" \
-noout -text \
>$outdir/$tag-ca.key.txt
echo "-- $tag-ca.crt.txt"
$prefix/bin/openssl x509 \
-in $outdir/$tag-ca.crt.pem \
-noout -text \
>$outdir/$tag-ca.crt.txt
# generate regular private keys and certificates
for type in server client object; do
eval "max=\$num_$type"
i=1
while [ $i -le $max ]; do
# determine name
name="$type"
if [ $max -gt 1 ]; then
name="$name$i"
fi
i=`expr $i + 1`
echo "++ generate $type private key and certificate"
# generate private key and certificate request
echo "-- $tag-$name.key.pem"
department=`$prefix/bin/perl -e 'printf("%s%s", uc(substr($ARGV[0], 0, 1)), substr($ARGV[0], 1));' $type`
keysize=1024
if [ ".$type" = .server ]; then
keysize=2048
fi
$prefix/bin/csp $tag request \
--csrfile=$outdir/$tag-$name.csr.pem \
--keyfile=$outdir/$tag-$name.key.pem \
--keysize=$keysize --keypass="$password" \
"CN=$name.$domain, OU=$department, O=$organization"
# generate server certificate
echo "-- $tag-$name.crt.pem"
echo "y" | $prefix/bin/csp $tag sign \
--csrfile=$outdir/$tag-$name.csr.pem \
--type=$type --days=$lifetime --capass="$password" >/dev/null
# cleanup by removing certificate request
rm -f $outdir/$tag-$name.csr.pem
# make all files available under common path
idx=`expr $idx + 1`
cp csp/$tag/certs/`echo . | awk '{ printf("%02X", idx); }' idx=$idx`.pem \
$outdir/$tag-$name.crt.pem
# provide textual presentations
echo "-- $tag-$name.key.txt"
$prefix/bin/openssl rsa \
-in $outdir/$tag-$name.key.pem -passin "pass:$password" \
-noout -text \
>$outdir/$tag-$name.key.txt
echo "-- $tag-$name.crt.txt"
$prefix/bin/openssl x509 \
-in $outdir/$tag-$name.crt.pem \
-noout -text \
>$outdir/$tag-$name.crt.txt
# make server private key insecure but necessarily unprotected
# for unattended use by a server daemon
if [ ".$type" = .server ]; then
$prefix/bin/openssl rsa \
-in $outdir/$tag-$name.key.pem -passin "pass:$password" \
-out $outdir/$tag-$name.key.pem.new 2>/dev/null
mv $outdir/$tag-$name.key.pem.new \
$outdir/$tag-$name.key.pem
fi
done
done
# cleanup
echo "++ deleting temporary location"
cd / || exit $?
rm -rf $tmpdir >/dev/null 2>&1 || true