Skip to content

Commit 176865f

Browse files
committed
generate-CA.sh: Update
Signed-off-by: Jianhui Zhao <[email protected]>
1 parent abf4fd6 commit 176865f

File tree

1 file changed

+16
-284
lines changed

1 file changed

+16
-284
lines changed

generate-CA.sh

+16-284
Original file line numberDiff line numberDiff line change
@@ -1,291 +1,23 @@
1-
#!/usr/bin/env bash
2-
#(@)generate-CA.sh - Create CA key-pair and server key-pair signed by CA
1+
#!/bin/bash
32

4-
# Copyright (c) 2013-2016 Jan-Piet Mens <jpmens()gmail.com>
5-
# All rights reserved.
6-
#
7-
# Redistribution and use in source and binary forms, with or without
8-
# modification, are permitted provided that the following conditions are met:
9-
#
10-
# 1. Redistributions of source code must retain the above copyright notice,
11-
# this list of conditions and the following disclaimer.
12-
# 2. Redistributions in binary form must reproduce the above copyright
13-
# notice, this list of conditions and the following disclaimer in the
14-
# documentation and/or other materials provided with the distribution.
15-
# 3. Neither the name of mosquitto nor the names of its
16-
# contributors may be used to endorse or promote products derived from
17-
# this software without specific prior written permission.
18-
#
19-
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20-
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21-
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22-
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23-
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24-
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25-
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26-
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27-
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28-
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29-
# POSSIBILITY OF SUCH DAMAGE.
3+
[ -n "$DEST" ] || DEST="."
304

31-
#
32-
# Usage:
33-
# ./generate-CA.sh creates ca.crt and server.{key,crt}
34-
# ./generate-CA.sh hostname creates hostname.{key,crt}
35-
# ./generate-CA.sh client email creates email.{key,crt}
36-
#
37-
# Set the following optional environment variables before invocation
38-
# to add the specified IP addresses and/or hostnames to the subjAltName list
39-
# These contain white-space-separated values
40-
#
41-
# IPLIST="172.13.14.15 192.168.1.1"
42-
# HOSTLIST="a.example.com b.example.com"
5+
mkdir -p "$DEST"
436

44-
set -e
7+
pushd "$DEST" || exit
458

46-
export LANG=C
9+
# CA certificate (FQDN must be different from server/client)
10+
openssl genrsa -out ca.key 2048
11+
openssl req -new -x509 -days 365 -key ca.key -subj "/C=CN/ST=GD/L=SZ/O=Acme, Inc./CN=Acme Root CA" -out ca.crt
4712

48-
kind=server
13+
# server certificate (for multiple domains, change subjectAltName to: DNS:example.com,DNS:www.example.com)
14+
openssl req -newkey rsa:2048 -nodes -keyout server.key -subj "/C=CN/ST=GD/L=SZ/O=Acme, Inc./CN=localhost" -out server.csr
15+
openssl x509 -sha256 -req -extfile <(printf "subjectAltName=DNS:localhost") -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
4916

50-
if [ $# -ne 2 ]; then
51-
kind=server
52-
host=$(hostname -f)
53-
if [ -n "$1" ]; then
54-
host="$1"
55-
fi
56-
else
57-
kind=client
58-
CLIENT="$2"
59-
fi
17+
# client certificate (the p12/pem format may be useful for some clients)
18+
openssl req -newkey rsa:2048 -nodes -keyout client.key -subj "/C=CN/ST=GD/L=SZ/O=Acme, Inc./CN=client" -out client.csr
19+
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt
20+
openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12
21+
openssl pkcs12 -in client.p12 -out client.pem -clcerts
6022

61-
[ -z "$USER" ] && USER=root
62-
63-
DIR=${TARGET:='.'}
64-
# A space-separated list of alternate hostnames (subjAltName)
65-
# may be empty ""
66-
ALTHOSTNAMES=${HOSTLIST}
67-
ALTADDRESSES=${IPLIST}
68-
CA_ORG='/O=OwnTracks.org/OU=generate-CA/[email protected]'
69-
CA_DN="/CN=An MQTT broker${CA_ORG}"
70-
CACERT=${DIR}/ca
71-
SERVER="${DIR}/${host}"
72-
SERVER_DN="/CN=${host}$CA_ORG"
73-
keybits=2048
74-
openssl=$(which openssl)
75-
MOSQUITTOUSER=${MOSQUITTOUSER:=$USER}
76-
77-
# Signature Algorithm. To find out which are supported by your
78-
# version of OpenSSL, run `openssl dgst -help` and set your
79-
# signature algorithm here. For example:
80-
#
81-
# defaultmd="-sha256"
82-
#
83-
defaultmd="-sha512"
84-
85-
function maxdays() {
86-
nowyear=$(date +%Y)
87-
years=$(expr 2032 - $nowyear)
88-
days=$(expr $years '*' 365)
89-
90-
echo $days
91-
}
92-
93-
function getipaddresses() {
94-
/sbin/ifconfig |
95-
grep -v tunnel |
96-
sed -En '/inet6? /p' |
97-
sed -Ee 's/inet6? (addr:)?//' |
98-
awk '{print $1;}' |
99-
sed -e 's/[%/].*//' |
100-
egrep -v '(::1|127\.0\.0\.1)' # omit loopback to add it later
101-
}
102-
103-
104-
function addresslist() {
105-
106-
ALIST=""
107-
for a in $(getipaddresses); do
108-
ALIST="${ALIST}IP:$a,"
109-
done
110-
ALIST="${ALIST}IP:127.0.0.1,IP:::1,"
111-
112-
for ip in $(echo ${ALTADDRESSES}); do
113-
ALIST="${ALIST}IP:${ip},"
114-
done
115-
for h in $(echo ${ALTHOSTNAMES}); do
116-
ALIST="${ALIST}DNS:$h,"
117-
done
118-
ALIST="${ALIST}DNS:localhost"
119-
echo $ALIST
120-
121-
}
122-
123-
days=$(maxdays)
124-
125-
if [ -n "$CAKILLFILES" ]; then
126-
rm -f $CACERT.??? $SERVER.??? $CACERT.srl
127-
fi
128-
129-
if [ ! -f $CACERT.crt ]; then
130-
131-
# ____ _
132-
# / ___| / \
133-
# | | / _ \
134-
# | |___ / ___ \
135-
# \____/_/ \_\
136-
#
137-
138-
# Create un-encrypted (!) key
139-
$openssl req -newkey rsa:${keybits} -x509 -nodes $defaultmd -days $days -extensions v3_ca -keyout $CACERT.key -out $CACERT.crt -subj "${CA_DN}"
140-
echo "Created CA certificate in $CACERT.crt"
141-
$openssl x509 -in $CACERT.crt -nameopt multiline -subject -noout
142-
143-
chmod 400 $CACERT.key
144-
chmod 444 $CACERT.crt
145-
chown $MOSQUITTOUSER $CACERT.*
146-
echo "Warning: the CA key is not encrypted; store it safely!"
147-
fi
148-
149-
150-
if [ $kind == 'server' ]; then
151-
152-
# ____
153-
# / ___| ___ _ ____ _____ _ __
154-
# \___ \ / _ \ '__\ \ / / _ \ '__|
155-
# ___) | __/ | \ V / __/ |
156-
# |____/ \___|_| \_/ \___|_|
157-
#
158-
159-
if [ ! -f $SERVER.key ]; then
160-
echo "--- Creating server key and signing request"
161-
$openssl genrsa -out $SERVER.key $keybits
162-
$openssl req -new $defaultmd \
163-
-out $SERVER.csr \
164-
-key $SERVER.key \
165-
-subj "${SERVER_DN}"
166-
chmod 400 $SERVER.key
167-
chown $MOSQUITTOUSER $SERVER.key
168-
fi
169-
170-
if [ -f $SERVER.csr -a ! -f $SERVER.crt ]; then
171-
172-
# There's no way to pass subjAltName on the CLI so
173-
# create a cnf file and use that.
174-
175-
CNF=`mktemp /tmp/cacnf.XXXXXXXX` || { echo "$0: can't create temp file" >&2; exit 1; }
176-
sed -e 's/^.*%%% //' > $CNF <<\!ENDconfig
177-
%%% [ JPMextensions ]
178-
%%% basicConstraints = critical,CA:false
179-
%%% nsCertType = server
180-
%%% keyUsage = nonRepudiation, digitalSignature, keyEncipherment
181-
%%% nsComment = "Broker Certificate"
182-
%%% subjectKeyIdentifier = hash
183-
%%% authorityKeyIdentifier = keyid,issuer:always
184-
%%% subjectAltName = $ENV::SUBJALTNAME
185-
%%% # issuerAltName = issuer:copy
186-
%%% ## nsCaRevocationUrl = http://mqttitude.org/carev/
187-
%%% ## nsRevocationUrl = http://mqttitude.org/carev/
188-
%%% certificatePolicies = ia5org,@polsection
189-
%%%
190-
%%% [polsection]
191-
%%% policyIdentifier = 1.3.5.8
192-
%%% CPS.1 = "http://localhost"
193-
%%% userNotice.1 = @notice
194-
%%%
195-
%%% [notice]
196-
%%% explicitText = "This CA is for a local MQTT broker installation only"
197-
%%% organization = "OwnTracks"
198-
%%% noticeNumbers = 1
199-
200-
!ENDconfig
201-
202-
SUBJALTNAME="$(addresslist)"
203-
export SUBJALTNAME # Use environment. Because I can. ;-)
204-
205-
echo "--- Creating and signing server certificate"
206-
$openssl x509 -req $defaultmd \
207-
-in $SERVER.csr \
208-
-CA $CACERT.crt \
209-
-CAkey $CACERT.key \
210-
-CAcreateserial \
211-
-CAserial "${DIR}/ca.srl" \
212-
-out $SERVER.crt \
213-
-days $days \
214-
-extfile ${CNF} \
215-
-extensions JPMextensions
216-
217-
rm -f $CNF
218-
chmod 444 $SERVER.crt
219-
chown $MOSQUITTOUSER $SERVER.crt
220-
fi
221-
else
222-
# ____ _ _ _
223-
# / ___| (_) ___ _ __ | |_
224-
# | | | | |/ _ \ '_ \| __|
225-
# | |___| | | __/ | | | |_
226-
# \____|_|_|\___|_| |_|\__|
227-
#
228-
229-
if [ ! -f $CLIENT.key ]; then
230-
echo "--- Creating client key and signing request"
231-
$openssl genrsa -out $CLIENT.key $keybits
232-
233-
CNF=`mktemp /tmp/cacnf-req.XXXXXXXX` || { echo "$0: can't create temp file" >&2; exit 1; }
234-
# Mosquitto's use_identity_as_username takes the CN attribute
235-
# so we're populating that with the client's name
236-
sed -e 's/^.*%%% //' > $CNF <<!ENDClientconfigREQ
237-
%%% [ req ]
238-
%%% distinguished_name = req_distinguished_name
239-
%%% prompt = no
240-
%%% output_password = secret
241-
%%%
242-
%%% [ req_distinguished_name ]
243-
%%% # O = OwnTracks
244-
%%% # OU = MQTT
245-
%%% # CN = Suzie Smith
246-
%%% CN = $CLIENT
247-
%%% # emailAddress = $CLIENT
248-
!ENDClientconfigREQ
249-
250-
$openssl req -new $defaultmd \
251-
-out $CLIENT.csr \
252-
-key $CLIENT.key \
253-
-config $CNF
254-
chmod 400 $CLIENT.key
255-
fi
256-
257-
if [ -f $CLIENT.csr -a ! -f $CLIENT.crt ]; then
258-
259-
CNF=`mktemp /tmp/cacnf-cli.XXXXXXXX` || { echo "$0: can't create temp file" >&2; exit 1; }
260-
sed -e 's/^.*%%% //' > $CNF <<\!ENDClientconfig
261-
%%% [ JPMclientextensions ]
262-
%%% basicConstraints = critical,CA:false
263-
%%% subjectAltName = email:copy
264-
%%% nsCertType = client,email
265-
%%% extendedKeyUsage = clientAuth,emailProtection
266-
%%% keyUsage = digitalSignature, keyEncipherment, keyAgreement
267-
%%% nsComment = "Client Broker Certificate"
268-
%%% subjectKeyIdentifier = hash
269-
%%% authorityKeyIdentifier = keyid,issuer:always
270-
271-
!ENDClientconfig
272-
273-
SUBJALTNAME="$(addresslist)"
274-
export SUBJALTNAME # Use environment. Because I can. ;-)
275-
276-
echo "--- Creating and signing client certificate"
277-
$openssl x509 -req $defaultmd \
278-
-in $CLIENT.csr \
279-
-CA $CACERT.crt \
280-
-CAkey $CACERT.key \
281-
-CAcreateserial \
282-
-CAserial "${DIR}/ca.srl" \
283-
-out $CLIENT.crt \
284-
-days $days \
285-
-extfile ${CNF} \
286-
-extensions JPMclientextensions
287-
288-
rm -f $CNF
289-
chmod 444 $CLIENT.crt
290-
fi
291-
fi
23+
popd || exit

0 commit comments

Comments
 (0)