Author: Paolo Lulli <paolo@lulli.net>
Add signing via intermediate CAs
iron/libexec/iron/iron-ca | 3 iron/libexec/iron/iron-ca~ | 250 +++++++++++++++++++++++++----- iron/libexec/iron/iron-certificate | 81 +++++++-- iron/libexec/iron/iron-certificate~ | 89 +++++++--- iron/libexec/iron/iron-client | 2 iron/libexec/iron/iron-service | 91 ++++++++--- iron/libexec/iron/iron-service~ | 189 +++++++++++++---------
diff --git a/iron/libexec/iron/iron-ca b/iron/libexec/iron/iron-ca index 7a010d2a9d76b02b0aaf0688d3dedf8d97cbe9fd..8920cf236facbd74c460f036c0ff1609548c8df7 100755 --- a/iron/libexec/iron/iron-ca +++ b/iron/libexec/iron/iron-ca @@ -100,7 +100,8 @@ ST = Sweden L = Gotenburg O = kevwe.se OU = kevwe.se -CN = kevwe.se +#CN = kevwe.se +CN = ${intermediate}.kevwe.se emailAddress = cto@kevwe.se [ req_attributes ] diff --git a/iron/libexec/iron/iron-ca~ b/iron/libexec/iron/iron-ca~ index ae29d3c293b1f81e305d56542fb9bbe9a3e7f92b..89fa66f55da4d929ef6fdc4ba6d5c8d3e717a2fd 100644 --- a/iron/libexec/iron/iron-ca~ +++ b/iron/libexec/iron/iron-ca~ @@ -1,8 +1,9 @@ -#! /bin/bash +#! /bin/bash # Usage: iron ca <setup|create|delete|reset> # Summary: manage CA # Help: This command groups commands used to setup config create delete a CA +KEYSIZE=4096 APPNAME="iron" CURRDIR=$(pwd) @@ -13,76 +14,233 @@ CURRENT_TSTAMP=$(date '+%Y%m%d%H%M') function ca_create() { - test -d $CAPATH || mkdir -p ./$CAPATH - CA_DAYS=3650 - openssl genrsa -out $CAPATH/ca.key 2048 - openssl req -batch -new -key $CAPATH/ca.key -out $CAPATH/ca.csr -config $CA_CONFIG_FILE - openssl x509 -req -days ${CA_DAYS} -in $CAPATH/ca.csr -signkey $CAPATH/ca.key -out $CAPATH/ca.crt + test -d $CAPATH || mkdir -p ./$CAPATH + CA_DAYS=3650 + openssl genrsa -out $CAPATH/ca.key ${KEYSIZE} + openssl req -batch -new -key $CAPATH/ca.key -out $CAPATH/ca.csr -config $CA_CONFIG_FILE + openssl x509 -req -days ${CA_DAYS} -in $CAPATH/ca.csr -signkey $CAPATH/ca.key -out $CAPATH/ca.crt -extensions v3_ca -extfile $RCDIR/CA/conf/openssl-ca-extensions.conf +} + +function intermediate_create() +{ + intermediate=$1 + test -d $CAPATH/$intermediate || mkdir -p ./$CAPATH/$intermediate + CA_DAYS=3650 + openssl genrsa -out $CAPATH/$intermediate/$intermediate-ca.key ${KEYSIZE} + openssl req -batch -new -key $CAPATH/$intermediate/$intermediate-ca.key \ + -out $CAPATH/$intermediate/$intermediate-ca.csr -config $CA_CONFIG_FILE + openssl x509 -req -days ${CA_DAYS} \ + -in $CAPATH/$intermediate-ca.csr \ + -signkey $CAPATH/$intermediate-ca.key \ + -out $CAPATH/$intermediate-ca.crt \ + -extensions v3_intermediate_ca \ + -extfile $RCDIR/CA/$intermediate/conf/openssl-intermediate-extensions.conf } function ca_home_setup_delete() { - echo "About to DELETE ca: are you sure? y/n" - read confirmation - if [ "$confirmation" = "y" ]; then - (rm -fr $RCDIR/CA ; rm $RCFILE) && echo "CA DELETED" - else - echo "SKIPPING" - exit -1 - fi + echo "About to DELETE ca: are you sure? y/n" + read confirmation + if [ "$confirmation" = "y" ]; then + (rm -fr $RCDIR/CA ; rm $RCFILE) && echo "CA DELETED" + else + echo "SKIPPING" + exit -1 + fi +} + +function intermediate_home_setup_delete() +{ + intermediate=$1 + echo "About to DELETE ca: are you sure? y/n" + read confirmation + if [ "$confirmation" = "y" ]; then + (rm -fr $RCDIR/CA/$intermediate ; rm $RCFILE) && echo "CA DELETED" + else + echo "SKIPPING" + exit -1 + fi +} + +function intermediate_home_setup_write() +{ + intermediate=$1 + test -d $RCDIR/CA/$intermediate && ( echo "CA exist, please delete before" && exit -1) + test -d $RCDIR/CA/$intermediate || mkdir -p $RCDIR/CA/$intermediate + test -d $RCDIR/CA/$intermediate/conf || mkdir -p $RCDIR/CA/$intermediate/conf + echo "CAPATH=$RCDIR/CA/$intermediate">${RCFILE} + echo "CA_CONFIG_FILE=$RCDIR/CA/$intermediate/conf/openssl-intermediate.conf">>${RCFILE} + cat<<__EOF__ >$RCDIR/CA/$intermediate/conf/openssl-intermediate-extensions.conf +[ v3_intermediate_ca ] +# Extensions for a typical intermediate CA +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = critical, CA:true, pathlen:0 +keyUsage = critical, digitalSignature, cRLSign, keyCertSign +__EOF__ + + + cat<<__EOF__ >$RCDIR/CA/$intermediate/conf/openssl-intermediate.conf +#RANDFILE = $ENV::HOME/.rnd + +[ req ] +default_bits = ${KEYSIZE} +default_keyfile = keyfile.pem +distinguished_name = req_distinguished_name +attributes = req_attributes +prompt = no +#output_password = abadpass +default_days =3650 +#x509_extensions = v3_ca + + +[ req_distinguished_name ] +C = SE +ST = Sweden +L = Gotenburg +O = kevwe.se +OU = kevwe.se +CN = kevwe.se +emailAddress = cto@kevwe.se + +[ req_attributes ] +challengePassword = blablabla + +[ v3_intermediate_ca ] +# Extensions for a typical intermediate CA +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = critical, CA:true, pathlen:0 +keyUsage = critical, digitalSignature, cRLSign, keyCertSign + +__EOF__ } function ca_home_setup_write() { - test -d $RCDIR/CA && ( echo "CA exist, please delete before" && exit -1) - test -d $RCDIR/CA || mkdir -p $RCDIR/CA - test -d $RCDIR/CA/conf || mkdir -p $RCDIR/CA/conf - echo "CAPATH=$RCDIR/CA">${RCFILE} - echo "CA_CONFIG_FILE=$RCDIR/CA/conf/openssl-ca.conf">>${RCFILE} + test -d $RCDIR/CA && ( echo "CA exist, please delete before" && exit -1) + test -d $RCDIR/CA || mkdir -p $RCDIR/CA + test -d $RCDIR/CA/conf || mkdir -p $RCDIR/CA/conf + echo "CAPATH=$RCDIR/CA">${RCFILE} + echo "CA_CONFIG_FILE=$RCDIR/CA/conf/openssl-ca.conf">>${RCFILE} + cat<<__EOF__ >$RCDIR/CA/conf/openssl-ca-extensions.conf +[ v3_ca ] +# Extensions for a typical CA +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = critical, CA:true +keyUsage = critical, digitalSignature, cRLSign, keyCertSign + +__EOF__ + + cat<<__EOF__ >$RCDIR/CA/conf/openssl-ca.conf -RANDFILE = $ENV::HOME/.rnd +#RANDFILE = $ENV::HOME/.rnd [ req ] -default_bits = 1024 +default_bits = ${KEYSIZE} default_keyfile = keyfile.pem distinguished_name = req_distinguished_name attributes = req_attributes prompt = no #output_password = abadpass default_days =3650 +#x509_extensions = v3_ca + [ req_distinguished_name ] -C = IT -ST = Italia -L = Roma -O = service.lulli.net -OU = service.lulli.net -#CN = ca.service.lulli.net -CN = service.lulli.net -emailAddress = info@service.lulli.net +C = SE +ST = Sweden +L = Gotenburg +O = kevwe.se +OU = kevwe.se +CN = kevwe.se +emailAddress = cto@kevwe.se [ req_attributes ] challengePassword = blablabla + +[ v3_intermediate_ca ] +# Extensions for a typical intermediate CA +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = critical, CA:true, pathlen:0 +keyUsage = critical, digitalSignature, cRLSign, keyCertSign + +[ usr_cert ] +# Extensions for client certificates +basicConstraints = CA:FALSE +nsCertType = client, email +nsComment = "OpenSSL Generated Client Certificate" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer +keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth, emailProtection + +[ server_cert ] +# Extensions for server certificates +basicConstraints = CA:FALSE +nsCertType = server +nsComment = "OpenSSL Generated Server Certificate" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +keyUsage = critical, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth + +[ crl_ext ] +# Extension for CRLs +authorityKeyIdentifier=keyid:always + +[ ocsp ] +# Extension for OCSP signing certificates +basicConstraints = CA:FALSE +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer +keyUsage = critical, digitalSignature +extendedKeyUsage = critical, OCSPSigning + __EOF__ } +if [ "$#" = 2 ];then + operation=$1 + intermediate=$1 + RCFILE="$HOME/"."$APPNAME/$intermediate-ca"".env" + if [ "$operation" = "create" ]; then + test -f ${RCFILE} || ( intermediate_home_setup_write $intermediate; echo "Edit values in ${RCFILE}"; exit -1) + source ${RCFILE} + intermediate_create $intermediate + exit 0 + fi + if [ "$operation" = "setup" ]; then + test -f ${RCFILE} || ( intermediate_home_setup_write $intermediate ; echo "Edit values in ${RCFILE}"; exit 0) + exit 0 + fi + if [ "$operation" = "delete" ]; then + intermediate_home_setup_delete $intermediate + exit 0 + fi +fi + if [ "$#" = 1 ];then - operation=$1 - RCFILE="$HOME/"."$APPNAME/default-ca"".env" - if [ "$operation" = "create" ]; then - test -f ${RCFILE} || ( ca_home_setup_write ; echo "Edit values in ${RCFILE}"; exit -1) - source ${RCFILE} - ca_create - fi - if [ "$operation" = "setup" ]; then - test -f ${RCFILE} || ( ca_home_setup_write ; echo "Edit values in ${RCFILE}"; exit 0) - #source ${RCFILE} - fi - if [ "$operation" = "delete" ]; then - ca_home_setup_delete - fi -else - echo "Usage: iron ca <create|setup|delete>" - exit -1 + operation=$1 + RCFILE="$HOME/"."$APPNAME/default-ca"".env" + if [ "$operation" = "create" ]; then + test -f ${RCFILE} || ( ca_home_setup_write ; echo "Edit values in ${RCFILE}"; exit -1) + source ${RCFILE} + ca_create + exit 0 + fi + if [ "$operation" = "setup" ]; then + test -f ${RCFILE} || ( ca_home_setup_write ; echo "Edit values in ${RCFILE}"; exit 0) + #source ${RCFILE} + exit 0 + fi + if [ "$operation" = "delete" ]; then + ca_home_setup_delete + exit 0 + fi fi +echo "Usage: iron ca <create|setup|delete> [intermediate]" +exit -1 diff --git a/iron/libexec/iron/iron-certificate b/iron/libexec/iron/iron-certificate index 682a2fb72e7394f7f95c50f88440695de5c9c681..9a4f87344ec151a11661d56709011a658f735387 100755 --- a/iron/libexec/iron/iron-certificate +++ b/iron/libexec/iron/iron-certificate @@ -1,5 +1,5 @@ #! /bin/bash -# Usage: $iron certificate <sign> <filename> +# Usage: $iron certificate <sign> <filename> [intermediate] # Summary: create certificates # Help: This command groups commands used to setup config create delete a certificate @@ -14,16 +14,22 @@ function certificate_sign() { service=$1 csrfile=$2 + intermediate=$3 client=$(basename $csrfile | sed -e 's/.csr$//') CLIENT_CERTPATH=$RCDIR/$service/certs CP=$CLIENT_CERTPATH/$client test -d ${CP} || mkdir -p ${CP} - openssl x509 -req -days 365 -CA $CAPATH/ca.crt -CAkey $CAPATH/ca.key -CAcreateserial -in $csrfile -out $CP/$client.crt + if [ "$intermediate" = "" ]; then + openssl x509 -req -days 365 -CA $CAPATH/ca.crt -CAkey $CAPATH/ca.key -CAcreateserial -in $csrfile -out $CP/$client.crt + else + openssl x509 -req -days 365 -CA $CAPATH/$intermediate-ca.crt -CAkey $CAPATH/$intermediate-ca.key -CAcreateserial -in $csrfile -out $CP/$client.crt + fi } function remote_client_write_setup() { service=$1 + intermediate=$2 mkdir -p $RCDIR/$service CLIENT_RCFILE="$RCDIR/$service/client-$client"".env" echo "REMOTE_RCDIR=$RCDIR">${CLIENT_RCFILE} @@ -41,6 +47,7 @@ remote_csr_user=$2 remote_csr_host=$3 remote_csrfile=$4 remote_ssh_identity_file=$5 + intermediate=$6 csrfile=$(basename $remote_csrfile) remote_certdir=$(dirname $remote_csrfile) client=$(basename $csrfile | sed -e 's/.csr$//') @@ -53,7 +60,11 @@ else scp $remote_csr_user@$remote_csr_host:$remote_csrfile $CP/$client.csr fi - openssl x509 -req -days 365 -CA $CAPATH/ca.crt -CAkey $CAPATH/ca.key -CAcreateserial -in $CP/$client.csr -out $CP/$client.crt + if [ "$intermediate" = "" ]; then + openssl x509 -req -days 365 -CA $CAPATH/ca.crt -CAkey $CAPATH/ca.key -CAcreateserial -in $CP/$client.csr -out $CP/$client.crt + else + openssl x509 -req -days 365 -CA $CAPATH/$intermediate.crt -CAkey $CAPATH/$intermediate-ca.key -CAcreateserial -in $CP/$client.csr -out $CP/$client.crt + fi if [ -f $remote_ssh_identity_file ]; then scp -i $remote_ssh_identity_file $CP/$client.crt $REMOTE_USER@$REMOTE_HOST:$remote_certdir @@ -66,10 +77,15 @@ function certificate_create() { service=$1 client=$2 + intermediate=$3 CLIENT_CERTPATH=$RCDIR/$service/certs CP=$CLIENT_CERTPATH/$client test -d ${CP} || mkdir -p ${CP} - openssl x509 -req -days 365 -CA $CAPATH/ca.crt -CAkey $CAPATH/ca.key -CAcreateserial -in $CP/$client.csr -out $CP/$client.crt + if [ "$intermediate" = "" ]; then + openssl x509 -req -days 365 -CA $CAPATH/ca.crt -CAkey $CAPATH/ca.key -CAcreateserial -in $CP/$client.csr -out $CP/$client.crt + else + openssl x509 -req -days 365 -CA $CAPATH/$intermediate-ca.crt -CAkey $CAPATH/$intermediate-ca.key -CAcreateserial -in $CP/$client.csr -out $CP/$client.crt + fi test -f $CP/$client.crt && echo "Created certificate in [$CP/$client.crt]" } @@ -77,35 +93,55 @@ function pkcs12_create() { service=$1 client=$2 + intermediate=$3 CLIENT_CERTPATH=$RCDIR/$service/certs CP=$CLIENT_CERTPATH/$client test -d ${CP} || mkdir -p ${CP} - openssl pkcs12 -export -clcerts -in $CP/$client.crt -inkey $CP/$client.key -out $CP/$client.p12\ - -name "${client}"\ - -CAfile ${CAPATH}/ca.crt -caname root + if [ "$intermediate" = "" ]; then + openssl pkcs12 -export -clcerts -in $CP/$client.crt -inkey $CP/$client.key -out $CP/$client.p12\ + -name "${client}"\ + -CAfile ${CAPATH}/ca.crt -caname root + else + openssl pkcs12 -export -clcerts -in $CP/$client.crt -inkey $CP/$client.key -out $CP/$client.p12\ + -name "${client}"\ + -CAfile ${CAPATH}/$intermediate/$intermediate-ca.crt -caname $intermediate + fi test -f $CP/$client.p12 && echo "Created PKCS12 (*.p12) in [$CP/$client.p12]" } -if [ "$#" = 3 ];then +if [ "$#" = 4 ];then + intermediate=$4 +else + intermediate="" +fi + +if [ "$#" > 2 ];then operation=$1 service=$2 - CA_RCFILE="$HOME/"."$APPNAME/default-ca"".env" + if [ "$intermediate" = "" ]; then + CA_RCFILE="$HOME/"."$APPNAME/default-ca"".env" + else + CA_RCFILE="$HOME/"."$APPNAME/$intermediate-ca"".env" + fi source ${CA_RCFILE} if [ "$operation" = "sign" ]; then csrfile=$3 - certificate_sign $service $csrfile + certificate_sign $service $csrfile $intermediate + exit 0 fi if [ "$operation" = "create" ]; then client=$3 - certificate_create $service $client - pkcs12_create $service $client + certificate_create $service $client $intermediate + pkcs12_create $service $client $intermediate + exit 0 fi if [ "$operation" = "renew" ]; then client=$3 - certificate_create $service $client - pkcs12_create $service $client + certificate_create $service $client $intermediate + pkcs12_create $service $client $intermediate + exit 0 fi if [ "$operation" = "remotesign" ]; then @@ -119,13 +155,14 @@ remote_ssh_identity_file=$REMOTE_SSH_IDENTITY_FILE remote_csr_user=$REMOTE_USER remote_csr_host=$REMOTE_HOST remote_csrfile=$REMOTE_RCDIR/$service/certs/$client/$client.csr - remote_certificate_sign $service $remote_csr_user $remote_csr_host $remote_csrfile $remote_ssh_identity_file + remote_certificate_sign $service $remote_csr_user $remote_csr_host $remote_csrfile $remote_ssh_identity_file $intermediate + exit 0 fi -else - echo "Usage:" - echo "\$iron certificate <sign> <service> <CSR-file>" - echo "\$iron certificate <create> <service> <client-id>" - echo "\$iron certificate <renew> <service> <client-id>" - echo "\$iron certificate <remotesign> <service><client-id>" - exit -1 fi + +echo "Usage:" +echo "\$iron certificate <sign> <service> <CSR-file> [intermediate]" +echo "\$iron certificate <create> <service> <client-id> [intermediate]" +echo "\$iron certificate <renew> <service> <client-id> [intermediate]" +echo "\$iron certificate <remotesign> <service><client-id> [intermediate]" +exit -1 diff --git a/iron/libexec/iron/iron-certificate~ b/iron/libexec/iron/iron-certificate~ index b8b983460baa366b8ef85da9dd16c387205efac5..f52dda5af1de00dcd7c85bab75eca8b5ee65e1f1 100644 --- a/iron/libexec/iron/iron-certificate~ +++ b/iron/libexec/iron/iron-certificate~ @@ -1,5 +1,5 @@ #! /bin/bash -# Usage: $iron certificate <sign> <filename> +# Usage: $iron certificate <sign> <filename> [intermediate] # Summary: create certificates # Help: This command groups commands used to setup config create delete a certificate @@ -14,16 +14,22 @@ function certificate_sign() { service=$1 csrfile=$2 + intermediate=$3 client=$(basename $csrfile | sed -e 's/.csr$//') CLIENT_CERTPATH=$RCDIR/$service/certs CP=$CLIENT_CERTPATH/$client test -d ${CP} || mkdir -p ${CP} + if [ "$intermediate" = "" ]; then openssl x509 -req -days 365 -CA $CAPATH/ca.crt -CAkey $CAPATH/ca.key -CAcreateserial -in $csrfile -out $CP/$client.crt +else + openssl x509 -req -days 365 -CA $CAPATH/$intermediate/$intermediate-ca.crt -CAkey $CAPATH/$intermediate/$intermediate-ca.key -CAcreateserial -in $csrfile -out $CP/$client.crt + fi } function remote_client_write_setup() { service=$1 + intermediate=$2 mkdir -p $RCDIR/$service CLIENT_RCFILE="$RCDIR/$service/client-$client"".env" echo "REMOTE_RCDIR=$RCDIR">${CLIENT_RCFILE} @@ -41,6 +47,7 @@ remote_csr_user=$2 remote_csr_host=$3 remote_csrfile=$4 remote_ssh_identity_file=$5 + intermediate=$6 csrfile=$(basename $remote_csrfile) remote_certdir=$(dirname $remote_csrfile) client=$(basename $csrfile | sed -e 's/.csr$//') @@ -52,9 +59,13 @@ scp -i $remote_ssh_identity_file $remote_csr_user@$remote_csr_host:$remote_csrfile $CP/$client.csr else scp $remote_csr_user@$remote_csr_host:$remote_csrfile $CP/$client.csr fi - - openssl x509 -req -days 365 -CA $CAPATH/ca.crt -CAkey $CAPATH/ca.key -CAcreateserial -in $CP/$client.csr -out $CP/$client.crt - + + if [ "$intermediate" = "" ]; then + openssl x509 -req -days 365 -CA $CAPATH/ca.crt -CAkey $CAPATH/ca.key -CAcreateserial -in $CP/$client.csr -out $CP/$client.crt + else + openssl x509 -req -days 365 -CA $CAPATH/$intermediate/$intermediate.crt -CAkey $CAPATH/$intermediate/$intermediate-ca.key -CAcreateserial -in $CP/$client.csr -out $CP/$client.crt + fi + if [ -f $remote_ssh_identity_file ]; then scp -i $remote_ssh_identity_file $CP/$client.crt $REMOTE_USER@$REMOTE_HOST:$remote_certdir else @@ -66,10 +77,15 @@ function certificate_create() { service=$1 client=$2 + intermediate=$3 CLIENT_CERTPATH=$RCDIR/$service/certs CP=$CLIENT_CERTPATH/$client test -d ${CP} || mkdir -p ${CP} - openssl x509 -req -days 365 -CA $CAPATH/ca.crt -CAkey $CAPATH/ca.key -CAcreateserial -in $CP/$client.csr -out $CP/$client.crt + if [ "$intermediate" = "" ]; then + openssl x509 -req -days 365 -CA $CAPATH/ca.crt -CAkey $CAPATH/ca.key -CAcreateserial -in $CP/$client.csr -out $CP/$client.crt + else + openssl x509 -req -days 365 -CA $CAPATH/$intermediate/$intermediate-ca.crt -CAkey $CAPATH/$intermediate/$intermediate-ca.key -CAcreateserial -in $CP/$client.csr -out $CP/$client.crt + fi test -f $CP/$client.crt && echo "Created certificate in [$CP/$client.crt]" } @@ -77,55 +93,76 @@ function pkcs12_create() { service=$1 client=$2 + intermediate=$3 CLIENT_CERTPATH=$RCDIR/$service/certs CP=$CLIENT_CERTPATH/$client test -d ${CP} || mkdir -p ${CP} - openssl pkcs12 -export -clcerts -in $CP/$client.crt -inkey $CP/$client.key -out $CP/$client.p12\ - -name "${client}"\ - -CAfile ${CAPATH}/ca.crt -caname root + if [ "$intermediate" = "" ]; then + openssl pkcs12 -export -clcerts -in $CP/$client.crt -inkey $CP/$client.key -out $CP/$client.p12\ + -name "${client}"\ + -CAfile ${CAPATH}/ca.crt -caname root + else + openssl pkcs12 -export -clcerts -in $CP/$client.crt -inkey $CP/$client.key -out $CP/$client.p12\ + -name "${client}"\ + -CAfile ${CAPATH}/$intermediate/$intermediate-ca.crt -caname $intermediate + fi test -f $CP/$client.p12 && echo "Created PKCS12 (*.p12) in [$CP/$client.p12]" } -if [ "$#" = 3 ];then +if [ "$#" = 4 ];then + intermediate=$4 +else + intermediate="" +fi + +if [ "$#" > 2 ];then operation=$1 service=$2 - CA_RCFILE="$HOME/"."$APPNAME/default-ca"".env" + if [ "$intermediate" = "" ]; then + CA_RCFILE="$HOME/"."$APPNAME/default-ca"".env" + else + CA_RCFILE="$HOME/"."$APPNAME/$intermediate-ca"".env" + fi source ${CA_RCFILE} if [ "$operation" = "sign" ]; then csrfile=$3 - certificate_sign $service $csrfile + certificate_sign $service $csrfile $intermediate + exit 0 fi if [ "$operation" = "create" ]; then client=$3 - certificate_create $service $client - pkcs12_create $service $client + certificate_create $service $client $intermediate + pkcs12_create $service $client $intermediate + exit 0 fi - + if [ "$operation" = "renew" ]; then client=$3 - certificate_create $service $client - pkcs12_create $service $client + certificate_create $service $client $intermediate + pkcs12_create $service $client $intermediate + exit 0 fi if [ "$operation" = "remotesign" ]; then client=$3 CLIENT_RCFILE="$RCDIR/$service/client-$client"".env" - test -f $CLIENT_RCFILE || echo "Edit $CLIENT_RCFILE first" - test -f $CLIENT_RCFILE || remote_client_write_setup "$service"; + test -f $CLIENT_RCFILE || echo "Edit $CLIENT_RCFILE first" + test -f $CLIENT_RCFILE || remote_client_write_setup "$service"; test -f $CLIENT_RCFILE && source ${CLIENT_RCFILE} test -f $CLIENT_RCFILE && echo "Reading RC from: ${CLIENT_RCFILE}" remote_ssh_identity_file=$REMOTE_SSH_IDENTITY_FILE remote_csr_user=$REMOTE_USER remote_csr_host=$REMOTE_HOST remote_csrfile=$REMOTE_RCDIR/$service/certs/$client/$client.csr - remote_certificate_sign $service $remote_csr_user $remote_csr_host $remote_csrfile $remote_ssh_identity_file + remote_certificate_sign $service $remote_csr_user $remote_csr_host $remote_csrfile $remote_ssh_identity_file $intermediate + exit 0 fi -else - echo "Usage:" - echo "\$iron certificate <sign> <service> <CSR-file>" - echo "\$iron certificate <create> <service> <client-id>" - echo "\$iron certificate <renew> <service> <client-id>" - echo "\$iron certificate <remotesign> <service><client-id>" - exit -1 fi + +echo "Usage:" +echo "\$iron certificate <sign> <service> <CSR-file> [intermediate]" +echo "\$iron certificate <create> <service> <client-id> [intermediate]" +echo "\$iron certificate <renew> <service> <client-id> [intermediate]" +echo "\$iron certificate <remotesign> <service><client-id> [intermediate]" +exit -1 diff --git a/iron/libexec/iron/iron-client b/iron/libexec/iron/iron-client index 329ab803159af90e5ccecd64c115bee3818c0471..c845afef2dd183cb4dac3f9374d79c464032f1d0 100755 --- a/iron/libexec/iron/iron-client +++ b/iron/libexec/iron/iron-client @@ -72,7 +72,7 @@ test -d $CAPATH || mkdir -p $CAPATH test -d $CLIENT_CERTPATH || mkdir -p $CLIENT_CERTPATH cat<<__EOF__ >$RCDIR/${DOMAIN}/conf/client-${client}.conf -RANDFILE = $ENV::HOME/.rnd +#RANDFILE = $ENV::HOME/.rnd [ req ] default_bits = 2048 diff --git a/iron/libexec/iron/iron-service b/iron/libexec/iron/iron-service index c59f7700d43aa934b01b2edff3041fb791ab3d97..5cf6fb481934ca77999e79a3bad5a19d886df295 100755 --- a/iron/libexec/iron/iron-service +++ b/iron/libexec/iron/iron-service @@ -1,11 +1,13 @@ #! /bin/bash -# Usage: iron service <service-name> <setup|create|delete> +# Usage: iron service <service-name> <setup|create|delete> [intermediate] # Summary: manage service/server certificate creation # Help: This command groups commands used to setup config create delete a CA APPNAME="iron" CURRDIR=$(pwd) +KEYSIZE=4096 + RCDIR=$HOME/.$APPNAME test -d $RCDIR || mkdir -p $RCDIR CURRENT_TSTAMP=$(date '+%Y%m%d%H%M') @@ -13,25 +15,39 @@ function service_create() { service=$1 + intermediate=$2 extfile="${RCDIR}/${service}/conf/v3.ext" test -d $CERTPATH || mkdir -p $CERTPATH - openssl genrsa -out $CERTPATH/server.key 2048 + openssl genrsa -out $CERTPATH/server.key ${KEYSIZE} openssl req -batch -new -key $CERTPATH/server.key -out $CERTPATH/server.csr -config $SERVER_CONFIG_FILE - openssl x509 -req -days 365 -CA $CAPATH/ca.crt -CAkey $CAPATH/ca.key -CAcreateserial -in $CERTPATH/server.csr \ - -signkey $CERTPATH/server.key -out $CERTPATH/server.crt #-extfile ${extfile} + if [ "$intermediate" = "" ]; then + openssl x509 -req -days 365 -CA $CAPATH/ca.crt -CAkey $CAPATH/ca.key -CAcreateserial -in $CERTPATH/server.csr \ + -signkey $CERTPATH/server.key -out $CERTPATH/server.crt -extensions server_cert -extfile ${extfile} + else + openssl x509 -req -days 365 -CA $CAPATH/$intermediate/$intermediate-ca.crt \ + -CAkey $CAPATH/$intermediate/$intermediate-ca.key -CAcreateserial -in $CERTPATH/server.csr \ + -signkey $CERTPATH/server.key -out $CERTPATH/server.crt -extensions server_cert -extfile ${extfile} + fi } function service_renew() { service=$1 + intermediate=$2 extfile="${RCDIR}/${service}/conf/v3.ext" test -d $CERTPATH || mkdir -p $CERTPATH openssl req -batch -new -key $CERTPATH/server.key -out $CERTPATH/server.csr -config $SERVER_CONFIG_FILE - openssl x509 -req -days 365 -CA $CAPATH/ca.crt -CAkey $CAPATH/ca.key -CAcreateserial -in $CERTPATH/server.csr \ - -signkey $CERTPATH/server.key -out $CERTPATH/server.crt #-extfile ${extfile} + if [ "$intermediate" = "" ]; then + openssl x509 -req -days 365 -CA $CAPATH/ca.crt \ + -CAkey $CAPATH/ca.key -CAcreateserial -in $CERTPATH/server.csr \ + -signkey $CERTPATH/server.key -out $CERTPATH/server.crt -extensions server_cert -extfile ${extfile} + else + openssl x509 -req -days 365 -CA $CAPATH/$intermediate/$intermediate-ca.crt\ + -CAkey $CAPATH/$intermediate/$intermediate-ca.key -CAcreateserial -in $CERTPATH/server.csr + fi } function service_home_setup_delete() @@ -58,33 +74,52 @@ echo "CAPATH=${RCDIR}/CA" >> ${RCFILE} echo "SERVER_CONFIG_FILE=${RCDIR}/${DOMAIN}/conf/openssl-server.conf" >> ${RCFILE} cat<<__EOF__ >$RCDIR/${DOMAIN}/conf/openssl-server.conf -RANDFILE = $ENV::HOME/.rnd +#RANDFILE = $ENV::HOME/.rnd [ req ] -default_bits = 2048 +default_bits = ${KEYSIZE} default_keyfile = keyfile.pem distinguished_name = req_distinguished_name attributes = req_attributes prompt = no #output_password = bliblablu +x509_extensions = server_cert [ req_distinguished_name ] C = SE ST = Sweden -L = Göteborg +L = Gotenburg O = ${DOMAIN} OU = ${DOMAIN} CN = ${DOMAIN} emailAddress = info@${DOMAIN} +[ server_cert ] +# Extensions for server certificates +basicConstraints = CA:FALSE +nsCertType = server +nsComment = "OpenSSL Generated Server Certificate" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +keyUsage = critical, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth + [ req_attributes ] #challengePassword = blablabla __EOF__ cat<<__EOF__ >$RCDIR/${DOMAIN}/conf/v3.ext -authorityKeyIdentifier=keyid,issuer -basicConstraints=CA:FALSE -keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment +[ server_cert ] +# Extensions for server certificates +basicConstraints = CA:FALSE +nsCertType = server +nsComment = "OpenSSL Generated Server Certificate" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +keyUsage = critical, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth + +#keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment subjectAltName = @alt_names [alt_names] @@ -93,34 +128,38 @@ DNS.2 = www.${DOMAIN} __EOF__ } -if [ "$#" = 2 ];then +if [ "$#" = 3 ];then + intermediate=$3 +else + intermediate="" +fi + +if [ "$#" > 1 ];then operation=$1 service=$2 RCFILE="$HOME/"."$APPNAME/service-${service}"".env" if [ "$operation" = "create" ]; then - echo "BEFORE" - test -f ${RCFILE} || ( service_home_setup_write $service; echo "Edit values in ${RCFILE}"; exit -1) - echo "AFTER" + test -f ${RCFILE} || ( service_home_setup_write $service $intermediate; echo "Edit values in ${RCFILE}"; exit -1) source ${RCFILE} - service_create $service + service_create $service $intermediate + exit 0 fi if [ "$operation" = "renew" ]; then - echo "BEFORE" - test -f ${RCFILE} || ( service_home_setup_write $service; echo "Edit values in ${RCFILE}"; exit -1) - echo "AFTER" + test -f ${RCFILE} || ( service_home_setup_write $service $intermediate; echo "Edit values in ${RCFILE}"; exit -1) source ${RCFILE} - service_renew $service + service_renew $service $intermediate + exit 0 fi if [ "$operation" = "setup" ]; then - test -f ${RCFILE} || ( service_home_setup_write $service; echo "Edit values in ${RCFILE}"; exit 0) + test -f ${RCFILE} || ( service_home_setup_write $service $intermediate; echo "Edit values in ${RCFILE}"; exit 0) fi if [ "$operation" = "delete" ]; then source ${RCFILE} - service_home_setup_delete $service + service_home_setup_delete $service $intermediate + exit 0 fi -else - echo "Usage: \$iron service <setup|create|renew|delete> <service>" - exit -1 fi +echo "Usage: \$iron service <setup|create|renew|delete> <service> [intermediate]" +exit -1 diff --git a/iron/libexec/iron/iron-service~ b/iron/libexec/iron/iron-service~ index 27e1eb65cebf436068aeb3c3d8df7763946aa6fc..6784758a354ebbe1b0ba3a459e578aca016e28bf 100644 --- a/iron/libexec/iron/iron-service~ +++ b/iron/libexec/iron/iron-service~ @@ -1,10 +1,12 @@ -#! /bin/bash -# Usage: iron service <service-name> <setup|create|delete> +#! /bin/bash +# Usage: iron service <service-name> <setup|create|delete> [intermediate] # Summary: manage service/server certificate creation # Help: This command groups commands used to setup config create delete a CA APPNAME="iron" CURRDIR=$(pwd) + +KEYSIZE=4096 RCDIR=$HOME/.$APPNAME test -d $RCDIR || mkdir -p $RCDIR @@ -12,87 +14,111 @@ CURRENT_TSTAMP=$(date '+%Y%m%d%H%M') function service_create() { - service=$1 - extfile="${RCDIR}/${service}/conf/v3.ext" - - test -d $CERTPATH || mkdir -p $CERTPATH - openssl genrsa -out $CERTPATH/server.key 2048 - openssl req -batch -new -key $CERTPATH/server.key -out $CERTPATH/server.csr -config $SERVER_CONFIG_FILE - #OLD::openssl x509 -req -days 365 -in $CERTPATH/server.csr -signkey $CERTPATH/server.key -out $CERTPATH/server.crt -# TODO: add v3 extension -# https://stackoverflow.com/questions/18233835/creating-an-x509-v3-user-certificate-by-signing-csr -# https://medium.com/@tbusser/creating-a-browser-trusted-self-signed-ssl-certificate-2709ce43fd15 - openssl x509 -req -days 365 -CA $CAPATH/ca.crt -CAkey $CAPATH/ca.key -CAcreateserial -in $CERTPATH/server.csr \ - -signkey $CERTPATH/server.key -out $CERTPATH/server.crt -extfile ${extfile} - #openssl ca -cert $CAPATH/ca.crt -keyfile $CAPATH/ca.key -in $CERTPATH/server.csr -out $CERTPATH/server.crt -config /home/paolo/.iron/dev.lulli.net/conf/openssl-server.conf - + service=$1 + intermediate=$2 + extfile="${RCDIR}/${service}/conf/v3.ext" + + test -d $CERTPATH || mkdir -p $CERTPATH + openssl genrsa -out $CERTPATH/server.key ${KEYSIZE} + openssl req -batch -new -key $CERTPATH/server.key -out $CERTPATH/server.csr -config $SERVER_CONFIG_FILE + if [ "$intermediate" = "" ]; then + openssl x509 -req -days 365 -CA $CAPATH/ca.crt -CAkey $CAPATH/ca.key -CAcreateserial -in $CERTPATH/server.csr \ + -signkey $CERTPATH/server.key -out $CERTPATH/server.crt -extensions server_cert -extfile ${extfile} + else + openssl x509 -req -days 365 -CA $CAPATH/$intermediate/$intermediate-ca.crt \ + -CAkey $CAPATH/$intermediate/$intermediate-ca.key -CAcreateserial -in $CERTPATH/server.csr \ + fi + } function service_renew() { - service=$1 - extfile="${RCDIR}/${service}/conf/v3.ext" - - test -d $CERTPATH || mkdir -p $CERTPATH - openssl req -batch -new -key $CERTPATH/server.key -out $CERTPATH/server.csr -config $SERVER_CONFIG_FILE - #OLD::openssl x509 -req -days 365 -in $CERTPATH/server.csr -signkey $CERTPATH/server.key -out $CERTPATH/server.crt - openssl x509 -req -days 365 -CA $CAPATH/ca.crt -CAkey $CAPATH/ca.key -CAcreateserial -in $CERTPATH/server.csr \ - -signkey $CERTPATH/server.key -out $CERTPATH/server.crt -extfile ${extfile} - #openssl ca -cert $CAPATH/ca.crt -keyfile $CAPATH/ca.key -in $CERTPATH/server.csr -out $CERTPATH/server.crt -config /home/paolo/.iron/dev.lulli.net/conf/openssl-server.conf - + service=$1 + intermediate=$2 + extfile="${RCDIR}/${service}/conf/v3.ext" + + test -d $CERTPATH || mkdir -p $CERTPATH + openssl req -batch -new -key $CERTPATH/server.key -out $CERTPATH/server.csr -config $SERVER_CONFIG_FILE + if [ "$intermediate" = "" ]; then + openssl x509 -req -days 365 -CA $CAPATH/ca.crt \ + -CAkey $CAPATH/ca.key -CAcreateserial -in $CERTPATH/server.csr \ + -signkey $CERTPATH/server.key -out $CERTPATH/server.crt -extensions server_cert -extfile ${extfile} +else + openssl x509 -req -days 365 -CA $CAPATH/$intermediate/$intermediate-ca.crt\ + -CAkey $CAPATH/$intermediate/$intermediate-ca.key -CAcreateserial -in $CERTPATH/server.csr \ + fi } function service_home_setup_delete() { - DOMAIN=$1 - echo "About to DELETE cert path: [$RCDIR/${DOMAIN}] are you sure? y/n" - read confirmation - if [ "$confirmation" = "y" ]; then - (rm -fr $RCDIR/${DOMAIN} ; rm -fr $RCFILE) && echo "CA DELETED" - else - echo "SKIPPING" - exit -1 - fi + DOMAIN=$1 + echo "About to DELETE cert path: [$RCDIR/${DOMAIN}] are you sure? y/n" + read confirmation + if [ "$confirmation" = "y" ]; then + (rm -fr $RCDIR/${DOMAIN} ; rm -fr $RCFILE) && echo "CA DELETED" + else + echo "SKIPPING" + exit -1 + fi } function service_home_setup_write() { - DOMAIN=$1 - test -d $RCDIR/${DOMAIN} && ( echo "Dir $RCDIR/${DOMAIN} exist, please delete before" && exit -1) - test -d $RCDIR/${DOMAIN} || mkdir -p $RCDIR/${DOMAIN} - test -d $RCDIR/${DOMAIN}/conf || mkdir -p $RCDIR/${DOMAIN}/conf - echo "CERTPATH=${RCDIR}/${DOMAIN}/certs" >> ${RCFILE} - echo "CAPATH=${RCDIR}/CA" >> ${RCFILE} - echo "SERVER_CONFIG_FILE=${RCDIR}/${DOMAIN}/conf/openssl-server.conf" >> ${RCFILE} - + DOMAIN=$1 + test -d $RCDIR/${DOMAIN} && ( echo "Dir $RCDIR/${DOMAIN} exist, please delete before" && exit -1) + test -d $RCDIR/${DOMAIN} || mkdir -p $RCDIR/${DOMAIN} + test -d $RCDIR/${DOMAIN}/conf || mkdir -p $RCDIR/${DOMAIN}/conf + echo "CERTPATH=${RCDIR}/${DOMAIN}/certs" >> ${RCFILE} + echo "CAPATH=${RCDIR}/CA" >> ${RCFILE} + echo "SERVER_CONFIG_FILE=${RCDIR}/${DOMAIN}/conf/openssl-server.conf" >> ${RCFILE} + cat<<__EOF__ >$RCDIR/${DOMAIN}/conf/openssl-server.conf -RANDFILE = $ENV::HOME/.rnd +#RANDFILE = $ENV::HOME/.rnd [ req ] -default_bits = 1024 +default_bits = ${KEYSIZE} default_keyfile = keyfile.pem distinguished_name = req_distinguished_name attributes = req_attributes prompt = no #output_password = bliblablu +x509_extensions = server_cert [ req_distinguished_name ] -C = IT -ST = Italia -L = Roma +C = SE +ST = Sweden +L = Gotenburg O = ${DOMAIN} OU = ${DOMAIN} CN = ${DOMAIN} emailAddress = info@${DOMAIN} +[ server_cert ] +# Extensions for server certificates +basicConstraints = CA:FALSE +nsCertType = server +nsComment = "OpenSSL Generated Server Certificate" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +keyUsage = critical, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth + [ req_attributes ] #challengePassword = blablabla __EOF__ + + cat<<__EOF__ >$RCDIR/${DOMAIN}/conf/v3.ext +[ server_cert ] +# Extensions for server certificates +basicConstraints = CA:FALSE +nsCertType = server +nsComment = "OpenSSL Generated Server Certificate" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +keyUsage = critical, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth - cat<<__EOF__ >$RCDIR/${DOMAIN}/conf/v3.ext -authorityKeyIdentifier=keyid,issuer -basicConstraints=CA:FALSE -keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment +#keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment subjectAltName = @alt_names [alt_names] @@ -101,34 +127,37 @@ DNS.2 = www.${DOMAIN} __EOF__ } -if [ "$#" = 2 ];then - operation=$1 - service=$2 - RCFILE="$HOME/"."$APPNAME/service-${service}"".env" - - if [ "$operation" = "create" ]; then - echo "BEFORE" - test -f ${RCFILE} || ( service_home_setup_write $service; echo "Edit values in ${RCFILE}"; exit -1) - echo "AFTER" - source ${RCFILE} - service_create $service - fi - if [ "$operation" = "renew" ]; then - echo "BEFORE" - test -f ${RCFILE} || ( service_home_setup_write $service; echo "Edit values in ${RCFILE}"; exit -1) - echo "AFTER" - source ${RCFILE} - service_renew $service - fi - if [ "$operation" = "setup" ]; then - test -f ${RCFILE} || ( service_home_setup_write $service; echo "Edit values in ${RCFILE}"; exit 0) - fi - if [ "$operation" = "delete" ]; then - source ${RCFILE} - service_home_setup_delete $service - fi +if [ "$#" = 3 ];then + intermediate=$3 else - echo "Usage: \$iron service <setup|create|renew|delete> <service>" - exit -1 + intermediate="" +fi +if [ "$#" = 2 ];then + operation=$1 + service=$2 + RCFILE="$HOME/"."$APPNAME/service-${service}"".env" + + if [ "$operation" = "create" ]; then + test -f ${RCFILE} || ( service_home_setup_write $service $intermediate; echo "Edit values in ${RCFILE}"; exit -1) + source ${RCFILE} + service_create $service $intermediate + exit 0 + fi + if [ "$operation" = "renew" ]; then + test -f ${RCFILE} || ( service_home_setup_write $service $intermediate; echo "Edit values in ${RCFILE}"; exit -1) + source ${RCFILE} + service_renew $service $intermediate + exit 0 + fi + if [ "$operation" = "setup" ]; then + test -f ${RCFILE} || ( service_home_setup_write $service $intermediate; echo "Edit values in ${RCFILE}"; exit 0) + fi + if [ "$operation" = "delete" ]; then + source ${RCFILE} + service_home_setup_delete $service $intermediate + exit 0 + fi fi +echo "Usage: \$iron service <setup|create|renew|delete> <service> [intermediate]" +exit -1