| 1 |
# Copyright 1999-2003 Gentoo Technologies, Inc.
|
| 2 |
# Distributed under the terms of the GNU General Public License v2
|
| 3 |
# $Header: /home/cvsroot/gentoo-x86/eclass/ssl-cert.eclass,v 1.2 2004/04/01 22:08:35 vapier Exp $
|
| 4 |
#
|
| 5 |
# Author: Max Kalika <max@gentoo.org>
|
| 6 |
#
|
| 7 |
# This eclass implements standard installation procedure for installing
|
| 8 |
# self-signed SSL certificates.
|
| 9 |
|
| 10 |
ECLASS=ssl-cert
|
| 11 |
INHERITED="$INHERITED $ECLASS"
|
| 12 |
|
| 13 |
# Conditionally depend on OpenSSL: allows inheretence
|
| 14 |
# without pulling extra packages if not needed
|
| 15 |
DEPEND="ssl? ( dev-libs/openssl )"
|
| 16 |
|
| 17 |
# Initializes variables and generates the needed
|
| 18 |
# OpenSSL configuration file and a CA serial file
|
| 19 |
#
|
| 20 |
# Access: private
|
| 21 |
gen_cnf() {
|
| 22 |
# Location of the config file
|
| 23 |
SSL_CONF="${T}/${$}ssl.cnf"
|
| 24 |
# Location of the CA serial file
|
| 25 |
SSL_SERIAL="${T}/${$}ca.ser"
|
| 26 |
# Location of some random files OpenSSL can use: don't use
|
| 27 |
# /dev/u?random here -- doesn't work properly on all platforms
|
| 28 |
SSL_RANDOM="${T}/evironment:${T}/eclass-debug.log:/etc/resolv.conf"
|
| 29 |
|
| 30 |
# These can be overridden in the ebuild
|
| 31 |
SSL_DAYS="${SSL_BITS:-730}"
|
| 32 |
SSL_BITS="${SSL_BITS:-1024}"
|
| 33 |
SSL_COUNTRY="${SSL_COUNTRY:-US}"
|
| 34 |
SSL_STATE="${SSL_STATE:-California}"
|
| 35 |
SSL_LOCALITY="${SSL_LOCALITY:-Santa Barbara}"
|
| 36 |
SSL_ORGANIZATION="${SSL_ORGANIZATION:-SSL Server}"
|
| 37 |
SSL_UNIT="${SSL_UNIT:-For Testing Purposes Only}"
|
| 38 |
SSL_COMMONNAME="${SSL_COMMONNAME:-localhost}"
|
| 39 |
SSL_EMAIL="${SSL_EMAIL:-root@localhost}"
|
| 40 |
|
| 41 |
# Create the CA serial file
|
| 42 |
echo "01" > "${SSL_SERIAL}"
|
| 43 |
|
| 44 |
# Create the config file
|
| 45 |
ebegin "Generating OpenSSL configuration"
|
| 46 |
cat <<-EOF > "${SSL_CONF}"
|
| 47 |
[ req ]
|
| 48 |
prompt = no
|
| 49 |
default_bits = ${SSL_BITS}
|
| 50 |
distinguished_name = req_dn
|
| 51 |
[ req_dn ]
|
| 52 |
C = ${SSL_COUNTRY}
|
| 53 |
ST = ${SSL_STATE}
|
| 54 |
L = ${SSL_LOCALITY}
|
| 55 |
O = ${SSL_ORGANIZATION}
|
| 56 |
OU = ${SSL_UNIT}
|
| 57 |
CN = ${SSL_COMMONNAME}
|
| 58 |
emailAddress = ${SSL_EMAIL}
|
| 59 |
EOF
|
| 60 |
eend $?
|
| 61 |
|
| 62 |
return $?
|
| 63 |
}
|
| 64 |
|
| 65 |
# Simple function to determine whether we're creating
|
| 66 |
# a CA (which should only be done once) or final part
|
| 67 |
#
|
| 68 |
# Access: private
|
| 69 |
get_base() {
|
| 70 |
if [ "${1}" ] ; then
|
| 71 |
echo "${T}/${$}ca"
|
| 72 |
else
|
| 73 |
echo "${T}/${$}server"
|
| 74 |
fi
|
| 75 |
}
|
| 76 |
|
| 77 |
# Generates an RSA key
|
| 78 |
#
|
| 79 |
# Access: private
|
| 80 |
gen_key() {
|
| 81 |
local base=`get_base $1`
|
| 82 |
ebegin "Generating ${SSL_BITS} bit RSA key${1:+ for CA}"
|
| 83 |
/usr/bin/openssl genrsa -rand "${SSL_RANDOM}" \
|
| 84 |
-out "${base}.key" "${SSL_BITS}" &> /dev/null
|
| 85 |
eend $?
|
| 86 |
|
| 87 |
return $?
|
| 88 |
}
|
| 89 |
|
| 90 |
# Generates a certificate signing request using
|
| 91 |
# the key made by gen_key()
|
| 92 |
#
|
| 93 |
# Access: private
|
| 94 |
gen_csr() {
|
| 95 |
local base=`get_base $1`
|
| 96 |
ebegin "Generating Certificate Signing Request${1:+ for CA}"
|
| 97 |
/usr/bin/openssl req -config "${SSL_CONF}" -new \
|
| 98 |
-key "${base}.key" -out "${base}.csr" &>/dev/null
|
| 99 |
eend $?
|
| 100 |
|
| 101 |
return $?
|
| 102 |
}
|
| 103 |
|
| 104 |
# Generates either a self-signed CA certificate using
|
| 105 |
# the csr and key made by gen_csr() and gen_key() or
|
| 106 |
# a signed server certificate using the CA cert previously
|
| 107 |
# created by gen_crt()
|
| 108 |
#
|
| 109 |
# Access: private
|
| 110 |
gen_crt() {
|
| 111 |
local base=`get_base $1`
|
| 112 |
if [ "${1}" ] ; then
|
| 113 |
ebegin "Generating self-signed X.509 Certificate for CA"
|
| 114 |
/usr/bin/openssl x509 -extfile "${SSL_CONF}" \
|
| 115 |
-days ${SSL_DAYS} -req -signkey "${base}.key" \
|
| 116 |
-in "${base}.csr" -out "${base}.crt" &>/dev/null
|
| 117 |
else
|
| 118 |
local ca=`get_base 1`
|
| 119 |
ebegin "Generating authority-signed X.509 Certificate"
|
| 120 |
/usr/bin/openssl x509 -extfile "${SSL_CONF}" \
|
| 121 |
-days ${SSL_DAYS} -req -CAserial "${SSL_SERIAL}" \
|
| 122 |
-CAkey "${ca}.key" -CA "${ca}.crt" \
|
| 123 |
-in "${base}.csr" -out "${base}.crt" &>/dev/null
|
| 124 |
fi
|
| 125 |
eend $?
|
| 126 |
|
| 127 |
return $?
|
| 128 |
}
|
| 129 |
|
| 130 |
# Generates a PEM file by concatinating the key
|
| 131 |
# and cert file created by gen_key() and gen_cert()
|
| 132 |
#
|
| 133 |
# Access: private
|
| 134 |
gen_pem() {
|
| 135 |
local base=`get_base $1`
|
| 136 |
ebegin "Generating PEM Certificate"
|
| 137 |
(cat "${base}.key"; echo; cat "${base}.crt") > "${base}.pem"
|
| 138 |
eend $?
|
| 139 |
|
| 140 |
return $?
|
| 141 |
}
|
| 142 |
|
| 143 |
# Uses all the private functions above to generate
|
| 144 |
# and install the requested certificates
|
| 145 |
#
|
| 146 |
# Access: public
|
| 147 |
docert() {
|
| 148 |
if [ $# -lt 1 ] ; then
|
| 149 |
eerror "At least one argument needed"
|
| 150 |
return 1;
|
| 151 |
fi
|
| 152 |
|
| 153 |
# Initialize configuration
|
| 154 |
gen_cnf || return 1
|
| 155 |
echo
|
| 156 |
|
| 157 |
# Generate a CA environment
|
| 158 |
gen_key 1 || return 1
|
| 159 |
gen_csr 1 || return 1
|
| 160 |
gen_crt 1 || return 1
|
| 161 |
echo
|
| 162 |
|
| 163 |
local count=0
|
| 164 |
for cert in "$@" ; do
|
| 165 |
# Sanitize and check the requested certificate
|
| 166 |
cert="`/usr/bin/basename "${cert}"`"
|
| 167 |
if [ -z "${cert}" ] ; then
|
| 168 |
ewarn "Invalid certification requested, skipping"
|
| 169 |
continue
|
| 170 |
fi
|
| 171 |
|
| 172 |
# Check for previous existence of generated files
|
| 173 |
for type in key crt pem ; do
|
| 174 |
if [ -e "${D}${INSDESTTREE}/${cert}.${type}" ] ; then
|
| 175 |
ewarn "${D}${INSDESTTREE}/${cert}.${type}: exists, skipping"
|
| 176 |
continue 2
|
| 177 |
fi
|
| 178 |
done
|
| 179 |
|
| 180 |
# Generate the requested files
|
| 181 |
gen_key || continue
|
| 182 |
gen_csr || continue
|
| 183 |
gen_crt || continue
|
| 184 |
gen_pem || continue
|
| 185 |
echo
|
| 186 |
|
| 187 |
# Install the generated files and set sane permissions
|
| 188 |
local base=`get_base`
|
| 189 |
newins "${base}.key" "${cert}.key"
|
| 190 |
fperms 0400 "${INSDESTTREE}/${cert}.key"
|
| 191 |
newins "${base}.csr" "${cert}.csr"
|
| 192 |
fperms 0444 "${INSDESTTREE}/${cert}.csr"
|
| 193 |
newins "${base}.crt" "${cert}.crt"
|
| 194 |
fperms 0444 "${INSDESTTREE}/${cert}.crt"
|
| 195 |
newins "${base}.pem" "${cert}.pem"
|
| 196 |
fperms 0400 "${INSDESTTREE}/${cert}.pem"
|
| 197 |
count=$((${count}+1))
|
| 198 |
done
|
| 199 |
|
| 200 |
# Resulting status
|
| 201 |
if [ ! ${count} ] ; then
|
| 202 |
eerror "No certificates were generated"
|
| 203 |
return 1
|
| 204 |
elif [ ${count} != ${#} ] ; then
|
| 205 |
ewarn "Some requested certificates were not generated"
|
| 206 |
fi
|
| 207 |
}
|