blob: 169a5ba29824be235abdd4f435a436c1bf82927c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
|
# Copyright 1999-2004 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/eclass/ssl-cert.eclass,v 1.16 2008/04/14 06:37:44 ulm 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"
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}
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
# Initialize configuration
gen_cnf || return 1
echo
# Generate a CA environment
gen_key 1 || return 1
gen_csr 1 || return 1
gen_crt 1 || 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} ] ; then
eerror "No certificates were generated"
return 1
elif [ ${count} != ${#} ] ; then
ewarn "Some requested certificates were not generated"
fi
}
|