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.
246 lines
6.2 KiB
246 lines
6.2 KiB
# Copyright 1999-2011 Gentoo Foundation
|
|
# Distributed under the terms of the GNU General Public License v2
|
|
# $Header: /var/cvsroot/gentoo-x86/eclass/ssl-cert.eclass,v 1.19 2011/08/22 04:46:32 vapier Exp $
|
|
|
|
# @ECLASS: ssl-cert.eclass
|
|
# @MAINTAINER:
|
|
# @AUTHOR:
|
|
# Max Kalika <max@gentoo.org>
|
|
# @BLURB: Eclass for SSL certificates
|
|
# @DESCRIPTION:
|
|
# This eclass implements a standard installation procedure for installing
|
|
# self-signed SSL certificates.
|
|
# @EXAMPLE:
|
|
# "install_cert /foo/bar" installs ${ROOT}/foo/bar.{key,csr,crt,pem}
|
|
|
|
# Conditionally depend on OpenSSL: allows inheretence
|
|
# without pulling extra packages if not needed
|
|
DEPEND="ssl? ( dev-libs/openssl )"
|
|
IUSE="ssl"
|
|
|
|
# @FUNCTION: gen_cnf
|
|
# @USAGE:
|
|
# @DESCRIPTION:
|
|
# Initializes variables and generates the needed
|
|
# OpenSSL configuration file and a CA serial file
|
|
#
|
|
# Access: private
|
|
gen_cnf() {
|
|
# Location of the config file
|
|
SSL_CONF="${T}/${$}ssl.cnf"
|
|
# Location of the CA serial file
|
|
SSL_SERIAL="${T}/${$}ca.ser"
|
|
# Location of some random files OpenSSL can use: don't use
|
|
# /dev/u?random here -- doesn't work properly on all platforms
|
|
SSL_RANDOM="${T}/environment:${T}/eclass-debug.log:/etc/resolv.conf"
|
|
|
|
# These can be overridden in the ebuild
|
|
SSL_DAYS="${SSL_DAYS:-730}"
|
|
SSL_BITS="${SSL_BITS:-1024}"
|
|
SSL_COUNTRY="${SSL_COUNTRY:-US}"
|
|
SSL_STATE="${SSL_STATE:-California}"
|
|
SSL_LOCALITY="${SSL_LOCALITY:-Santa Barbara}"
|
|
SSL_ORGANIZATION="${SSL_ORGANIZATION:-SSL Server}"
|
|
SSL_UNIT="${SSL_UNIT:-For Testing Purposes Only}"
|
|
SSL_COMMONNAME="${SSL_COMMONNAME:-localhost}"
|
|
SSL_EMAIL="${SSL_EMAIL:-root@localhost}"
|
|
|
|
# Create the CA serial file
|
|
echo "01" > "${SSL_SERIAL}"
|
|
|
|
# Create the config file
|
|
ebegin "Generating OpenSSL configuration${1:+ for CA}"
|
|
cat <<-EOF > "${SSL_CONF}"
|
|
[ req ]
|
|
prompt = no
|
|
default_bits = ${SSL_BITS}
|
|
distinguished_name = req_dn
|
|
[ req_dn ]
|
|
C = ${SSL_COUNTRY}
|
|
ST = ${SSL_STATE}
|
|
L = ${SSL_LOCALITY}
|
|
O = ${SSL_ORGANIZATION}
|
|
OU = ${SSL_UNIT}
|
|
CN = ${SSL_COMMONNAME}${1:+ CA}
|
|
emailAddress = ${SSL_EMAIL}
|
|
EOF
|
|
eend $?
|
|
|
|
return $?
|
|
}
|
|
|
|
# @FUNCTION: get_base
|
|
# @USAGE: [if_ca]
|
|
# @RETURN: <base path>
|
|
# @DESCRIPTION:
|
|
# Simple function to determine whether we're creating
|
|
# a CA (which should only be done once) or final part
|
|
#
|
|
# Access: private
|
|
get_base() {
|
|
if [ "${1}" ] ; then
|
|
echo "${T}/${$}ca"
|
|
else
|
|
echo "${T}/${$}server"
|
|
fi
|
|
}
|
|
|
|
# @FUNCTION: gen_key
|
|
# @USAGE: <base path>
|
|
# @DESCRIPTION:
|
|
# Generates an RSA key
|
|
#
|
|
# Access: private
|
|
gen_key() {
|
|
local base=`get_base $1`
|
|
ebegin "Generating ${SSL_BITS} bit RSA key${1:+ for CA}"
|
|
/usr/bin/openssl genrsa -rand "${SSL_RANDOM}" \
|
|
-out "${base}.key" "${SSL_BITS}" &> /dev/null
|
|
eend $?
|
|
|
|
return $?
|
|
}
|
|
|
|
# @FUNCTION: gen_csr
|
|
# @USAGE: <base path>
|
|
# @DESCRIPTION:
|
|
# Generates a certificate signing request using
|
|
# the key made by gen_key()
|
|
#
|
|
# Access: private
|
|
gen_csr() {
|
|
local base=`get_base $1`
|
|
ebegin "Generating Certificate Signing Request${1:+ for CA}"
|
|
/usr/bin/openssl req -config "${SSL_CONF}" -new \
|
|
-key "${base}.key" -out "${base}.csr" &>/dev/null
|
|
eend $?
|
|
|
|
return $?
|
|
}
|
|
|
|
# @FUNCTION: gen_crt
|
|
# @USAGE: <base path>
|
|
# @DESCRIPTION:
|
|
# Generates either a self-signed CA certificate using
|
|
# the csr and key made by gen_csr() and gen_key() or
|
|
# a signed server certificate using the CA cert previously
|
|
# created by gen_crt()
|
|
#
|
|
# Access: private
|
|
gen_crt() {
|
|
local base=`get_base $1`
|
|
if [ "${1}" ] ; then
|
|
ebegin "Generating self-signed X.509 Certificate for CA"
|
|
/usr/bin/openssl x509 -extfile "${SSL_CONF}" \
|
|
-days ${SSL_DAYS} -req -signkey "${base}.key" \
|
|
-in "${base}.csr" -out "${base}.crt" &>/dev/null
|
|
else
|
|
local ca=`get_base 1`
|
|
ebegin "Generating authority-signed X.509 Certificate"
|
|
/usr/bin/openssl x509 -extfile "${SSL_CONF}" \
|
|
-days ${SSL_DAYS} -req -CAserial "${SSL_SERIAL}" \
|
|
-CAkey "${ca}.key" -CA "${ca}.crt" \
|
|
-in "${base}.csr" -out "${base}.crt" &>/dev/null
|
|
fi
|
|
eend $?
|
|
|
|
return $?
|
|
}
|
|
|
|
# @FUNCTION: gen_pem
|
|
# @USAGE: <base path>
|
|
# @DESCRIPTION:
|
|
# Generates a PEM file by concatinating the key
|
|
# and cert file created by gen_key() and gen_cert()
|
|
#
|
|
# Access: private
|
|
gen_pem() {
|
|
local base=`get_base $1`
|
|
ebegin "Generating PEM Certificate"
|
|
(cat "${base}.key"; echo; cat "${base}.crt") > "${base}.pem"
|
|
eend $?
|
|
|
|
return $?
|
|
}
|
|
|
|
# Removed due to bug 174759
|
|
docert() {
|
|
eerror "Function \"docert\" has been removed for security reasons."
|
|
eerror "\"install_cert\" should be used instead. See bug 174759."
|
|
die
|
|
}
|
|
|
|
# @FUNCTION: install_cert
|
|
# @USAGE: <certificates>
|
|
# @DESCRIPTION:
|
|
# Uses all the private functions above to generate and install the
|
|
# requested certificates.
|
|
# <certificates> are full pathnames relative to ROOT, without extension.
|
|
#
|
|
# Example: "install_cert /foo/bar" installs ${ROOT}/foo/bar.{key,csr,crt,pem}
|
|
#
|
|
# Access: public
|
|
install_cert() {
|
|
if [ $# -lt 1 ] ; then
|
|
eerror "At least one argument needed"
|
|
return 1;
|
|
fi
|
|
|
|
case ${EBUILD_PHASE} in
|
|
unpack|compile|test|install)
|
|
eerror "install_cert cannot be called in ${EBUILD_PHASE}"
|
|
return 1 ;;
|
|
esac
|
|
|
|
# Generate a CA environment #164601
|
|
gen_cnf 1 || return 1
|
|
gen_key 1 || return 1
|
|
gen_csr 1 || return 1
|
|
gen_crt 1 || return 1
|
|
echo
|
|
|
|
gen_cnf || return 1
|
|
echo
|
|
|
|
local count=0
|
|
for cert in "$@" ; do
|
|
# Check the requested certificate
|
|
if [ -z "${cert##*/}" ] ; then
|
|
ewarn "Invalid certification requested, skipping"
|
|
continue
|
|
fi
|
|
|
|
# Check for previous existence of generated files
|
|
for type in key csr crt pem ; do
|
|
if [ -e "${ROOT}${cert}.${type}" ] ; then
|
|
ewarn "${ROOT}${cert}.${type}: exists, skipping"
|
|
continue 2
|
|
fi
|
|
done
|
|
|
|
# Generate the requested files
|
|
gen_key || continue
|
|
gen_csr || continue
|
|
gen_crt || continue
|
|
gen_pem || continue
|
|
echo
|
|
|
|
# Install the generated files and set sane permissions
|
|
local base=$(get_base)
|
|
install -d "${ROOT}${cert%/*}"
|
|
install -m0400 "${base}.key" "${ROOT}${cert}.key"
|
|
install -m0444 "${base}.csr" "${ROOT}${cert}.csr"
|
|
install -m0444 "${base}.crt" "${ROOT}${cert}.crt"
|
|
install -m0400 "${base}.pem" "${ROOT}${cert}.pem"
|
|
count=$((${count}+1))
|
|
done
|
|
|
|
# Resulting status
|
|
if [ ${count} = 0 ] ; then
|
|
eerror "No certificates were generated"
|
|
return 1
|
|
elif [ ${count} != ${#} ] ; then
|
|
ewarn "Some requested certificates were not generated"
|
|
fi
|
|
}
|