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