Alon Bar-Lev has uploaded a new change for review. Change subject: pki: split enroll out of create CA ......................................................................
pki: split enroll out of create CA the enroll functionality is handy after installation, and soon to be used by the websocketproxy setup if enabled, either manually or automatically. at this chance we drop the installCA in favour of single CreateCA script, add error handling and named parameters. yet there is a long way to go to cleanup the pki module. Change-Id: I8f3a8ae1fb061532cdafd5bc7961c5178d7948a0 Signed-off-by: Alon Bar-Lev <alo...@redhat.com> --- M packaging/etc/pki/CreateCA.sh M packaging/etc/pki/cacert.template.in A packaging/etc/pki/enroll.sh D packaging/etc/pki/installCA.sh M packaging/fedora/setup/engine-setup.py M packaging/setup/ovirt_engine_setup/constants.py M packaging/setup/plugins/ovirt-engine-setup/pki/ca.py 7 files changed, 262 insertions(+), 155 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/99/15499/1 diff --git a/packaging/etc/pki/CreateCA.sh b/packaging/etc/pki/CreateCA.sh index 5b89a55..6032405 100755 --- a/packaging/etc/pki/CreateCA.sh +++ b/packaging/etc/pki/CreateCA.sh @@ -1,47 +1,120 @@ #!/bin/sh -usage() { - cat << __EOF__ -CreateCA.sh - Creates Certificate Authority certificate and keys -USAGE: - $0 [Country] [Organization] [Name] [startdate] -Where: - Country = 2 Letters country code - Organization = Organization name string - Name = CA Subject Name - startdate = in YYMMDDHHMMSSZ ASN1 format -__EOF__ +die() { + local m="$1" + echo "$m" >&2 exit 1 } -[ "$#" -eq 4 ] || usage +enroll() { + local subject="$1" -cp cacert.template cacert.conf -echo "C = $1" >> cacert.conf -echo "O = $2" >> cacert.conf -echo "CN = $3" >> cacert.conf -cp cert.template cert.conf -chmod a+r cacert.conf cert.conf + cp cacert.template cacert.conf || die "Cannot create cacert.conf" + cp cert.template cert.conf | die "Cannot create cert.conf" + chmod a+r cacert.conf cert.conf || die "Cannot set config files permissions" -# -# openssl ca directory must -# be writable for the user -# as backup files are produced -# so let's assume directory -# is in correct permissions -# -echo 1000 > serial.txt -rm -f database.txt* -touch database.txt .rnd -chown --reference=. serial.txt* database.txt* .rnd* + # + # openssl ca directory must + # be writable for the user + # as backup files are produced + # so let's assume directory + # is in correct permissions + # + echo 1000 > serial.txt || die "Cannot write to serial.txt" + rm -f database.txt* + touch database.txt .rnd || die "Cannot write to database.txt" + chown --reference=. serial.txt* database.txt* .rnd* || die "Cannot set database permissions" -openssl genrsa -out private/ca.pem 2048 && \ - openssl req -new -key private/ca.pem \ - -config cacert.conf -out requests/ca.csr && \ - openssl ca -selfsign -out ca.pem -in requests/ca.csr \ - -keyfile private/ca.pem -days 3650 -startdate "$4" \ - -config openssl.conf -extfile cacert.conf \ - -extensions v3_ca -batch && \ - openssl x509 -in ca.pem -out certs/ca.der -chmod a+r ca.pem certs/ca.der -chown --reference=private private/ca.pem + touch private/ca.pem + chown --reference=private private/ca.pem || die "Cannot set CA private key permissions" + openssl genrsa \ + -out private/ca.pem \ + 2048 \ + || die "Cannot generate CA key" + openssl req \ + -new \ + -key private/ca.pem \ + -config cacert.conf \ + -subj "/" \ + -batch \ + -out requests/ca.csr \ + || die "Cannot generate CA request" + openssl ca \ + -selfsign \ + -out ca.pem \ + -in requests/ca.csr \ + -keyfile private/ca.pem \ + -subj "${subject}" \ + -days 3650 \ + -startdate "$(date --utc --date "now -1 days" +"%y%m%d%H%M%S%z")" \ + -config openssl.conf \ + -extfile cacert.conf \ + -extensions v3_ca \ + -batch \ + || die "Cannot enroll CA certificate" + openssl x509 -in ca.pem -out certs/ca.der || die "Cannot read CA certificate" + chmod a+r ca.pem certs/ca.der || die "Cannot set CA certificate permissions" + + return 0 +} + +keystore() { + local password="$1" + + keytool \ + -delete \ + -noprompt \ + -alias cacert \ + -keystore ./.truststore \ + -storepass "${password}" + keytool \ + -import \ + -noprompt \ + -trustcacerts \ + -alias cacert \ + -keypass "${password}" \ + -file certs/ca.der \ + -keystore ./.truststore \ + -storepass "${password}" \ + || die "Keystore import failed" + + return 0 +} + +usage() { + cat << __EOF__ +$0 + --subject=subject X.500 subject name. +__EOF__ +} + +while [ -n "$1" ]; do + x="$1" + v="${x#*=}" + shift + case "${x}" in + --subject=*) + SUBJECT="${v}" + ;; + --keystore-password=*) + KEYSTORE_PASSWORD="${v}" + ;; + --help) + usage + exit 0 + ;; + *) + usage + exit 1 + ;; + esac +done + +[ -n "${SUBJECT}" ] || die "Please specify subject" + +SCRIPTDIR="$(dirname "$0")" +PKIDIR="${SCRIPTDIR}" +cd "${PKIDIR}" + +enroll "${SUBJECT}" +keystore "${KEYSTORE_PASSWORD}" diff --git a/packaging/etc/pki/cacert.template.in b/packaging/etc/pki/cacert.template.in index 5a19136..3608860 100644 --- a/packaging/etc/pki/cacert.template.in +++ b/packaging/etc/pki/cacert.template.in @@ -7,7 +7,6 @@ distinguished_name = req_distinguished_name attributes = req_attributes x509_extensions = v3_ca -prompt = no output_password = NoSoup4U [req_attributes] diff --git a/packaging/etc/pki/enroll.sh b/packaging/etc/pki/enroll.sh new file mode 100755 index 0000000..c90f8a6 --- /dev/null +++ b/packaging/etc/pki/enroll.sh @@ -0,0 +1,96 @@ +#!/bin/sh + +die() { + local m="$1" + echo "$m" >&2 + exit 1 +} + +enroll() { + local name="$1" + local pass="$2" + local subj="$3" + + openssl \ + req \ + -newkey rsa:2048 \ + -days 365 \ + -out "${PKIDIR}/requests/${name}.req" \ + -keyout "${TMPKEY}" \ + -passout "pass:${pass}" \ + -subj "${subj}" \ + || die "Cannot create certificate request" + + "${PKIDIR}/SignReq.sh" \ + "${name}.req" \ + "${name}.cer" \ + 1800 \ + "${PKIDIR}" \ + "$(date --utc --date "now -1 days" +"%y%m%d%H%M%S%z")" \ + "${pass}" \ + || die "Cannot sign request" + [ -s "${PKIDIR}/certs/${name}.cer" ] || die "Certificate enrollment failed" + + touch "${PKIDIR}/keys/${name}.p12" + chmod go-rwx "${PKIDIR}/keys/${name}.p12" + openssl \ + pkcs12 \ + -export \ + -in "${PKIDIR}/certs/${name}.cer" \ + -inkey "${TMPKEY}" \ + -passin "pass:${pass}" \ + -out "${PKIDIR}/keys/${name}.p12" \ + -passout "pass:${pass}" \ + || die "Cannot createPKCS#12" + + return 0 +} + +usage() { + cat << __EOF__ +$0 + --name=prefix file name without prefix. + --password=password password of PKCS#12. + --subject=subject X.500 subject name. +__EOF__ +} + +while [ -n "$1" ]; do + x="$1" + v="${x#*=}" + shift + case "${x}" in + --name=*) + NAME="${v}" + ;; + --password=*) + PASSWORD="${v}" + ;; + --subject=*) + SUBJECT="${v}" + ;; + --help) + usage + exit 0 + ;; + *) + usage + exit 1 + ;; + esac +done + +[ -n "${NAME}" ] || die "Please specify name" +[ -n "${PASSWORD}" ] || die "Please specify password" +[ -n "${SUBJECT}" ] || die "Please specify subject" + +SCRIPTDIR="$(dirname "$0")" +PKIDIR="${SCRIPTDIR}" + +TMPKEY="$(mktemp)" +cleanup() { + rm -f "${TMPKEY}" +} +trap cleanup 0 + +enroll "${NAME}" "${PASSWORD}" "${SUBJECT}" diff --git a/packaging/etc/pki/installCA.sh b/packaging/etc/pki/installCA.sh deleted file mode 100755 index fa0e7e5..0000000 --- a/packaging/etc/pki/installCA.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/bin/sh - -ENGINE_KEY="/tmp/engine.$$.key" -cleanup() { - rm -f "${ENGINE_KEY}" -} -trap cleanup 0 - -die() { - local m="$1" - echo "$m" >&2 - exit 1 -} - -usage() { - DATE=`date --utc --date "now -1 days" +"%y%m%d%H%M%S%z"` - cat << __EOF__ -Usage: - $0 [Subject] [Country] [Organization] [Alias] [Password] [ANSI Start Date] [Working Directory] [CA Subject] -e.g.: - $0 hostname.fqdn US oVirt engine NoSoup4U $DATE -__EOF__ - - exit 1 -} - -enroll_certificate() { - local name="$1" - local pass="$2" - local subj="$3" - - echo " " - echo "}} Creating Engine Key..." - openssl req -newkey rsa:2048 -days 365 -out "requests/${name}.req" -keyout "${ENGINE_KEY}" -passout "pass:${pass}" -subj "${subj}" || die "Cannot create certificate request" - chmod go-rwx "requests/${name}.req" "${ENGINE_KEY}" - - echo " " - echo "}} Signing certificate request..." - ./SignReq.sh "${name}.req" "${name}.cer" 1800 "$(pwd)" "${DATE}" "${pass}" - [ -s "certs/${name}.cer" ] || die "file 'certs/${name}.cer' does not exist!" - - echo " " - echo "}} Creating PKCS#12 store..." - openssl pkcs12 -export -in "certs/${name}.cer" -inkey "${ENGINE_KEY}" -passin "pass:${pass}" -out "keys/${name}.p12" -passout "pass:${pass}" || die "Cannot createPKCS#12" - chmod go-rwx "keys/${name}.p12" -} - -# Set var's -SUBJECT="$1" -COUNTRY="$2" -ORG="$3" -ALIAS="$4" -PASS="$5" -DATE="$6" -WORKDIR="$7" -CA_SUBJECT="$8" - -[ -n "${CA_SUBJECT}" ] || usage - -[ -d "$7" ] || die "Directory $7 does not exists" - -echo " " -echo "} Creating CA..." - -# Move to scripts location -cd "$WORKDIR" - -# Create CA -./CreateCA.sh "$COUNTRY" "$ORG" "CA-$CA_SUBJECT" "$DATE" \ - || die "CreateCA.sh exited with errors" -[ -s private/ca.pem ] || die "file private/ca.pem does not exist!" -[ -s ca.pem ] || die "file ca.pem does not exist!" -[ -s certs/ca.der ] || die "file certs/ca.der does not exist!" - -# Import CA into keystore -echo " " -echo "> Importing CA certificate..." -# Generate truststore -keytool -delete -noprompt -alias cacert -keystore ./.truststore -storepass "$PASS" > /dev/null 2>&1 -keytool -import -noprompt -trustcacerts -alias cacert -keypass "$PASS" -file certs/ca.der -keystore ./.truststore -storepass "$PASS" -chmod a+r ./.truststore - -echo " " -echo "} Creating client certificates for oVirt..." -enroll_certificate engine "$PASS" "/C=${COUNTRY}/O=${ORG}/CN=${SUBJECT}" -enroll_certificate apache "$PASS" "/C=${COUNTRY}/O=${ORG}/CN=${SUBJECT}" -enroll_certificate jboss "$PASS" "/C=${COUNTRY}/O=${ORG}/CN=${SUBJECT}" - -exit 0 - diff --git a/packaging/fedora/setup/engine-setup.py b/packaging/fedora/setup/engine-setup.py index 613e4cc..c501466 100755 --- a/packaging/fedora/setup/engine-setup.py +++ b/packaging/fedora/setup/engine-setup.py @@ -818,11 +818,6 @@ if not os.path.exists(basedefs.FILE_CA_CRT_SRC): _updateCaCrtTemplate() - # We create the CA with yesterday's starting date - yesterday = datetime.datetime.utcnow() - datetime.timedelta(1) - date = yesterday.strftime("%y%m%d%H%M%S+0000") - logging.debug("Date string is %s", date) - # Add random string to certificate CN field randInt = random.randint(10000,99999) @@ -834,19 +829,35 @@ # Create the CA cmd = [ - os.path.join(basedefs.DIR_OVIRT_PKI, "installCA.sh"), - controller.CONF["HOST_FQDN"], - basedefs.CONST_CA_COUNTRY, - controller.CONF["ORG_NAME"], - basedefs.CONST_CA_ALIAS, - basedefs.CONST_CA_PASS, - date, - basedefs.DIR_OVIRT_PKI, - uniqueCN, + os.path.join(basedefs.DIR_OVIRT_PKI, "CreateCA.sh"), + "--subject=/C=%s/O=%s/CN=%s" % ( + basedefs.CONST_CA_COUNTRY, + controller.CONF["ORG_NAME"], + uniqueCN, + ), + "--keystore-password=%s" % basedefs.CONST_CA_PASS, ] out, rc = utils.execCmd(cmdList=cmd, failOnError=True, msg=output_messages.ERR_RC_CODE, maskList=[basedefs.CONST_CA_PASS]) + # Enroll certificates + for name in ('engine', 'apache', 'jboss'): + utils.execCmd( + cmdList=( + os.path.join(basedefs.DIR_OVIRT_PKI, "enroll.sh"), + "--name=%s" % name, + "--password=%s" % basedefs.CONST_CA_PASS, + "--subject=/C=%s/O=%s/CN=%s" % ( + basedefs.CONST_CA_COUNTRY, + controller.CONF["ORG_NAME"], + controller.CONF["HOST_FQDN"], + ), + ), + failOnError=True, + msg=output_messages.ERR_RC_CODE, + maskList=[basedefs.CONST_CA_PASS], + ) + # Extract non password key for log collector cmd = [ basedefs.EXEC_OPENSSL, diff --git a/packaging/setup/ovirt_engine_setup/constants.py b/packaging/setup/ovirt_engine_setup/constants.py index 57f4168..e23663f 100644 --- a/packaging/setup/ovirt_engine_setup/constants.py +++ b/packaging/setup/ovirt_engine_setup/constants.py @@ -163,7 +163,11 @@ ) OVIRT_ENGINE_PKI_CA_CREATE = os.path.join( OVIRT_ENGINE_PKIDIR, - 'installCA.sh', + 'CreateCA.sh', + ) + OVIRT_ENGINE_PKI_CA_ENROLL = os.path.join( + OVIRT_ENGINE_PKIDIR, + 'enroll.sh', ) OVIRT_ENGINE_PKI_ENGINE_STORE = os.path.join( OVIRT_ENGINE_PKIKEYSDIR, diff --git a/packaging/setup/plugins/ovirt-engine-setup/pki/ca.py b/packaging/setup/plugins/ovirt-engine-setup/pki/ca.py index 44a4f7e8..be6f789 100644 --- a/packaging/setup/plugins/ovirt-engine-setup/pki/ca.py +++ b/packaging/setup/plugins/ovirt-engine-setup/pki/ca.py @@ -168,25 +168,39 @@ ), ) - yesterday = datetime.datetime.utcnow() - datetime.timedelta(1) self.execute( ( osetupcons.FileLocations.OVIRT_ENGINE_PKI_CA_CREATE, - self.environment[osetupcons.ConfigEnv.FQDN], - self.environment[osetupcons.PKIEnv.COUNTRY], - self.environment[osetupcons.PKIEnv.ORG], - 'engine', - self.environment[osetupcons.PKIEnv.STORE_PASS], - yesterday.strftime('%y%m%d%H%M%S+0000'), - osetupcons.FileLocations.OVIRT_ENGINE_PKIDIR, - '%s.%s' % ( + '--subject=/C=%s/O=%s/CN=%s.%s' % ( + self.environment[osetupcons.PKIEnv.COUNTRY], + self.environment[osetupcons.PKIEnv.ORG], self.environment[ osetupcons.ConfigEnv.FQDN ][:MAX_HOST_FQDN_LEN], random.randint(10000, 99999), - ) + ), + '--keystore-password=%s' % ( + self.environment[osetupcons.PKIEnv.STORE_PASS], + ), ), ) + + for name in ('engine', 'apache', 'jboss'): + self.execute( + ( + osetupcons.FileLocations.OVIRT_ENGINE_PKI_CA_ENROLL, + '--name=%s' % name, + '--password=%s' % ( + self.environment[osetupcons.PKIEnv.STORE_PASS], + ), + '--subject=/C=%s/O=%s/CN=%s' % ( + self.environment[osetupcons.PKIEnv.COUNTRY], + self.environment[osetupcons.PKIEnv.ORG], + self.environment[osetupcons.ConfigEnv.FQDN], + ), + ), + ) + uninstall_files.extend( ( osetupcons.FileLocations.OVIRT_ENGINE_PKI_APACHE_CERT, -- To view, visit http://gerrit.ovirt.org/15499 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I8f3a8ae1fb061532cdafd5bc7961c5178d7948a0 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Alon Bar-Lev <alo...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches