#!/bin/bash

source $(dirname ${BASH_SOURCE[0]})/processman

#
# KEY
#

# create a key
function openssl_key()
{
  key_file=$1
  openssl genrsa -rand /dev/urandom -out $key_file 2048
}

#
# CA certificate
#

function openssl_setup_ca()
{
  dir="$1"
  name="trustworthy-ca.suse.cz"

  mkdir -p $dir/ca
  
  echo Generating CA configuration
  echo ---------------------------
  cat >$dir/ca/openssl.conf <<EOT
[ ca ]
default_ca      = CA_default            # The default ca section

[ CA_default ]

dir            = $dir/ca               # Where everything is kept
certs          = $dir/ca/certs/        # Where the issued certs are kept
crl_dir        = $dir/crl/             # Where the issued crl are kept
database       = $dir/ca/cert.index    # Database index file
new_certs_dir  = $dir/ca/newcerts/     # Default place for new certs
certificate    = $dir/ca/my.crt        # The CA certificate
serial         = $dir/ca/cert.serial   # The current serial number
crlnumber      = $dir/ca/crl.number    # CRL serial number
crl            = $dir/ca/my.crl        # The current CRL  
private_key    = $dir/ca/private.key   # CA private key
RANDFILE       = $dir/ca/.rand         # Private random number file

default_days     = 365                 # how long to certify for
default_crl_days = 30                  # how long before next CRL
default_md       = sha1                # md to use

policy           = policy_any          # default policy

[ policy_any ]
countryName            = supplied
stateOrProvinceName    = optional
organizationName       = optional
organizationalUnitName = optional
commonName             = supplied
emailAddress           = optional

[ req ]
default_bits           = 2048
distinguished_name     = req_distinguished_name
attributes             = req_attributes
prompt                 = no
output_password        = mypass

[ req_distinguished_name ]
C                      = "CZ"
ST                     = "Czech Republic"
L                      = "Prague"
O                      = "SUSE Linux SERVER"
OU                     = "R&D"
CN                     = "$name"
emailAddress           = "webmaster@$name"

[ req_attributes ]
challengePassword      = $RANDOM

EOT

  echo 01 > $dir/ca/cert.serial
  mkdir -p $dir/ca/certs/
  mkdir -p $dir/ca/newcerts/
  touch $dir/ca/cert.index
  touch $dir/ca/cert.index.attr
  echo 01 > $dir/ca/crl.number  
  echo --- Done.

  echo Generating CA key
  echo -----------------
  openssl_key $dir/ca/private.key
  echo --- Done.

  echo Generating CA certificate
  echo -------------------------
  openssl req -config $dir/ca/openssl.conf -new -x509 -days 365 -key $dir/ca/private.key -out $dir/ca/my.crt
  echo --- Done.
}

#
# entity cert
#

function openssl_setup_entity()
{
  dir="$1"
  entity_name="$2"

  mkdir -p $dir/$entity_name

  echo Generating entity configuration
  echo -------------------------------
  cat > $dir/$entity_name/openssl.conf <<EOT
[ req ]
distinguished_name     = req_distinguished_name
attributes             = req_attributes
prompt                 = no
output_password        = mypass
req_extensions         = x509v3

[ req_distinguished_name ]
C                      = "CZ"
ST                     = "Czech Republic"
L                      = "Prague"
O                      = "SUSE Linux SERVER"
OU                     = "R&D"
CN                     = "$entity_name"
emailAddress           = "webmaster@$entity_name"

[ x509v3 ]
subjectAltName         = DNS:$entity_name
extendedKeyUsage       = OCSPSigning
authorityInfoAccess    = OCSP;URI:http://127.0.0.1:$AREX_OCSP_PORT

[ req_attributes ]
challengePassword      = $RANDOM
EOT
  echo Done.
 
  echo Generating entity key
  echo ---------------------
  openssl_key $dir/$entity_name/private.key
  echo Done.

  echo Generating entity CSR
  echo ---------------------
  openssl req -config $dir/$entity_name/openssl.conf -new -key $dir/$entity_name/private.key -out $dir/$entity_name/my.csr
  echo --- Done.

  echo Generating entity certificate
  echo -----------------------------
  openssl ca -batch -config $dir/ca/openssl.conf -in $dir/$entity_name/my.csr -out $dir/$entity_name/my.crt
  echo --- Done.
}

#
# CRL
#


# add a certificate to CRL
function openssl_ca_revoke_cert()
{
  dir=$1
  entity_name=$2
  openssl ca -config $dir/ca/openssl.conf -revoke $dir/$entity_name/my.crt
  openssl ca -config $dir/ca/openssl.conf -gencrl -out $dir/ca/my.crl
}

#
# OCSP
#

# start OCSP responder daemon for our CA
function openssl_ocsp_responder_start()
{
  dir=$1
  openssl ocsp -index $dir/ca/cert.index \
               -port $AREX_OCSP_PORT \
               -rsigner $dir/ca/my.crt \
               -rkey $dir/ca/private.key \
               -CA $dir/ca/my.crt \
               -text &> $dir/ocsp-responder.log &
  sleep 1
  echo $(get_pid_port $AREX_OCSP_PORT) > $dir/ocsp-responder.pid
}

# stop OCSP responder
function openssl_ocsp_responder_stop()
{
  dir=$1
  pid=$(cat $dir/ocsp-responder.pid)
  return $(kill_pid_port $pid $AREX_OCSP_PORT)
}

# get a status of the certificate of an entity
function openssl_ocsp_cert_status()
{
  dir=$1
  entity_name=$2

  openssl ocsp -CAfile $dir/ca/my.crt \
               -issuer $dir/ca/my.crt \
               -cert $dir/$entity_name/my.crt \
               -url http://127.0.0.1:$AREX_OCSP_PORT \
               -text 2>/dev/null \
               | grep 'Cert Status' | sed 's/.*Cert Status:[^a-z]*\([a-z]*\)[^a-z]*/\1/'
}

function openssl_pem_to_der()
{
  pem_file=$1
  der_file=$2
  openssl rsa -in $pem_file -inform pem -out $der_file -outform der
}

