#!/bin/bash
SSLDIR="/var/ssl/ca"
export PASS=„testpas“
export CAPASS=„capass“
export COU="de"
export STA="rlp"
export CIT="zw“
export COM="xinux"
export UNI="it"
export MAI="technik@xinux.de"
export CAN="xin-ca"
export CRLWEB="URI:http://www.xinux.de/ca/$CAN.crl"

function openssl-cf()
{
cat <<HERE 
HOME                    = .
#RANDFILE                = $ENV::HOME/.rnd
oid_section             = new_oids
[ new_oids ]
tsa_policy1 = 1.2.3.4.1
tsa_policy2 = 1.2.3.4.5.6
tsa_policy3 = 1.2.3.4.5.7
[ ca ]
default_ca      = CA_default            
[ CA_default ]
dir             = ./                     
certs           = \$dir/certs            
crl_dir         = \$dir/crl              
database        = \$dir/index.txt        
new_certs_dir   = \$dir/newcerts         
certificate     = \$dir/$CAN.crt           
serial          = \$dir/serial           
crlnumber       = \$dir/crlnumber         
crl             = \$dir/$CAN.crl      
private_key     = \$dir/$CAN.key            
#RANDFILE        = $dir/private/.rand    
x509_extensions = usr_cert              
copy_extensions	= copy  # add by xinux 
name_opt        = ca_default           
cert_opt        = ca_default           
default_days    = 3650  # change by xinux               
default_crl_days= 30                  
default_md      = default            
preserve        = no                
policy          = policy_match
[ policy_match ]
countryName             = match
stateOrProvinceName     = optional
localityName            = optional
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
[ policy_anything ]
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
[ req ]
default_bits            = 2048
default_keyfile         = privkey.pem
distinguished_name      = req_distinguished_name
attributes              = req_attributes
x509_extensions = v3_ca 
string_mask = utf8only
[ req_distinguished_name ]
countryName                     = Country Name (2 letter code)
countryName_default             = $COUNTRY
countryName_min                 = 2
countryName_max                 = 2
stateOrProvinceName             = State or Province Name (full name)
stateOrProvinceName_default     = $PROVINCE
localityName                    = Locality Name (eg, city)
localityName_default            = $CITY
0.organizationName              = Organization Name (eg, company)
0.organizationName_default      = $ORGANIZATION
organizationalUnitName          = Organizational Unit Name (eg, section)
organizationalUnitName_default  = $UNIT
commonName                      = Common Name (eg, YOUR name)
commonName_max                  = 64
commonName_default              = $COMMONNAME
#emailAddress                    = Email Address
#emailAddress_max                = 64
#emailAddress_default            = $MAILADDRESS
[ req_attributes ]
[ usr_cert ]
basicConstraints=CA:FALSE
nsComment                       = "OpenSSL Generated Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ] # change by xinux
basicConstraints = CA:true
basicConstraints       = critical, CA:TRUE
keyUsage               = cRLSign, keyCertSign
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid, issuer:always
subjectAltName         = email:copy
issuerAltName          = issuer:copy
crlDistributionPoints  = $CRLWEB 
[ crl_ext ]
authorityKeyIdentifier=keyid:always
[ proxy_cert_ext ]
basicConstraints=CA:FALSE
nsComment                       = "OpenSSL Generated Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
[ tsa ]
default_tsa = tsa_config1       
[ tsa_config1 ]
dir             = ./demoCA          
serial          = $dir/tsaserial     
crypto_device   = builtin             
signer_cert     = $dir/tsacert.pem     
certs           = $dir/cacert.pem      
signer_key      = $dir/private/tsakey.pem 
default_policy  = tsa_policy1          
other_policies  = tsa_policy2, tsa_policy3     
digests         = md5, sha1            
accuracy        = secs:1, millisecs:500, microsecs:100 
clock_precision_digits  = 0     
ordering                = yes   
tsa_name                = yes  
ess_cert_id_chain       = no    
HERE
}

function ask()
{
echo -ne "Country Name (2 letter code) [$COU]: "
read COUNTRY
test -z $COUNTRY && COUNTRY="$COU"
echo -ne "State or Province Name (full name) [$STA]: "
read PROVINCE
test -z $PROVINCE && PROVINCE="$STA"
echo -ne "Locality Name (eg, city) [$CIT]: "
read CITY
test -z $CITY && CITY="$CIT"
echo -ne "Organization Name (eg, company) [xinux] "
read ORGANIZATION
test -z $ORGANIZATION && ORGANIZATION="xinux"
echo -ne "Organizational Unit Name (eg, section) [$UNI]: "
read UNIT
test -z $UNIT && UNIT="$UNI"
case $1 in
ca)
echo -ne "Common Name (CA name) [$CON] : "
read COMMONNAME
test -z $COMMONNAME && COMMONNAME="$CON" 
;;
cert)
echo -ne "Common Name (e.g. server FQDN or YOUR name) [this is requiured] : "
read COMMONNAME
test -z $COMMONNAME && { echo COMMONNAME is required ; exit 1 ; }  
;;
esac
#echo -ne "Email Address [$MAI]: "
#read MAILADDRESS
#test -z $MAILADDRESS && MAILADDRESS="$MAI"
}



function ca()
{
CON=$CAN
ask ca
export COUNTRY PROVINCE CITY COMMONNAME UNIT MAILADDRESS
if [ -d $SSLDIR ]; then
 echo "CA exist!"
 exit 1
else
 mkdir -p $SSLDIR/newcerts
 cd $SSLDIR
 touch index.txt
 echo 01 > serial
 echo 01 > crlnumber
fi
openssl-cf > openssl.cnf
openssl genrsa -passout env:CAPASS -des3 -out $CAN.key 2048
openssl req -passin env:CAPASS -new -batch -config openssl.cnf -key $CAN.key -x509 -sha1 -days 3650 -out $CAN.crt
echo -e "\nCA created!\n"
}

function cert()
{
test "$1" = "server" && { shift ; EXT="server"; }
test "$1" = "client" && { shift ; EXT="client"; }
if test -d $SSLDIR 
then 
cd $SSLDIR
else
echo "$SSLDIR not found" 
exit 1 
fi 
if test "$#" -eq 1
then
COMMONNAME=$1
test -f $COMMONNAME.key && { echo "$COMMONNAME exists" ; exit 1; } 
sed -e "s/commonName_default.\+/commonName_default\t\t= $COMMONNAME/" openssl.cnf > $COMMONNAME.cnf
else
unset COMMONNAME
ask cert
test -f $COMMONNAME.key && { echo "$COMMONNAME exists" ; exit 1; } 
openssl-cf > $COMMONNAME.cnf
fi
openssl genrsa -out $COMMONNAME.key 2048
case $EXT in
server)
cat<<HERE >> $COMMONNAME.cnf
[ server-ext ]
extendedKeyUsage = serverAuth, 1.3.6.1.5.5.8.2.2
subjectAltName = DNS:$COMMONNAME
HERE
openssl req -new -batch -config $COMMONNAME.cnf -key $COMMONNAME.key  -out $COMMONNAME.csr -reqexts server-ext 
;;
client)
cat<<HERE >> $COMMONNAME.cnf
[ client-ext ]
extendedKeyUsage = clientAuth
HERE
openssl req  -new -batch -config $COMMONNAME.cnf -key $COMMONNAME.key  -out $COMMONNAME.csr -reqexts client-ext 
;;
*)
openssl req  -new -batch -config $COMMONNAME.cnf -key $COMMONNAME.key  -out $COMMONNAME.csr
;;
esac 
openssl ca  -passin env:CAPASS -config openssl.cnf -batch -cert $CAN.crt -days 3650 -md sha1 -keyfile $CAN.key   -in $COMMONNAME.csr  -out $COMMONNAME.crt
openssl ca -passin env:CAPASS -batch -gencrl -config openssl.cnf -out $CAN.crl
openssl  crl -in $CAN.crl -outform der -out crl-der.crl
openssl pkcs12  -passout env:PASS  -export -in $COMMONNAME.crt -inkey $COMMONNAME.key -certfile $CAN.crt -out $COMMONNAME.p12
echo -e "\ncert created\n"
#pac-swan $COMMONNAME
}


function revoke()
{
cd $SSLDIR
COMMONNAME=$1
openssl ca -passin env:CAPASS -config openssl.cnf -revoke $COMMONNAME.crt
echo -e "\ncert $COMMONNAME revoke\n"
}


function dh()
{
cd $SSLDIR
openssl gendh 1024 > dh1024.pem:
echo -e "\ndh generated\n"
}

function list()
{
cd $SSLDIR
cat index.txt
}
function help()
{

cat<<HERE
"$0" 

ca "generate a CA"

cert "interactive"

cert server "interaktiv serverext"

cert client "interaktiv clientext"

cert <COMMONNAME> "interactive" 

cert server <COMMONNAME> "interactive serverext" 

cert client <COMMONNAME> "interactive clientext" 

revoke <COMMONNAME> "revoke a cert"

dh "generate diffie-hellmann" 

list "list certs"

show req  <COMMONNAME> "show request"

show cert <COMMONNAME> "show cert"

help "this help"

HERE

}

function show()
{
cd $SSLDIR
case $1 in
cert) 
test -f $2.crt ||  { echo "$2.crt not found"; exit 1;}
openssl x509 -noout -text -in $2.crt
;;
req)
test -f $2.csr || { echo "$2.csr not found"; exit 1 ;}
openssl req -noout -text -in $2.csr
;;
*)
echo "second arg must be req odr cert"
;;
esac 
}



echo -e "working directory: $SSLDIR\n"
test -d $SSLDIR || { echo "first create CA" ; DF=1 ; }

case $1 in 
ca) ca ;;
cert) cert $2 $3 ;;
revoke) revoke $2 ;;
dh) dh ;;
show) show $2 $3 ;;
list) list ;;
help) help ;;
*) 
echo "$0 ca | cert [server|client] <COMMONNAME>  | revoke <COMMONNAME> | dh | list | show <cert|req> COMMMON_NAME | help";; 
esac
