forked from Linaro/lite_bootstrap_server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
setup-ca.sh
executable file
·163 lines (129 loc) · 5.05 KB
/
setup-ca.sh
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
#!/usr/bin/env bash
# Copyright (c) 2022, Linaro. All rights reserved.
# SPDX-License-Identifier: BSD-3-Clause
# Exit on command failure
set -o errexit
# Fail on unset variable
# Use "${VARNAME-}" instead of "$VARNAME" to access unset variable(s)
set -o nounset
# Enable debug mode if $TRACE is set
# To enable, run with: "env TRACE=1 ./setup-ca.sh"
if [[ "${TRACE-0}" == "1" ]]; then
set -o xtrace
fi
# Check for too many parameters
if [ $# -gt 1 ]
then
echo "Too many paramters provided."
echo "Run './setup-ca.sh -h' for help."
exit 1
fi
# Check if the first arg is -h or --help
if [[ "${1-}" =~ ^-*h(elp)?$ ]]; then
echo "Usage: ./setup-ca.sh [hostname]
Generates private keys and certificates for the CA, as well as the TLS
server used by the REST API.
The following files are placed them in the 'certs' folder:
- certs/CA.crt Certificate for the CA key used to sign certificates
- certs/CA.key Private CA key used to sign certificates (do not share!)
- certs/CA.srl Serial number for the CA certificate
- certs/SERVER.crt Certificate used during TLS handshakes on the server(s)
- certs/SERVER.key Private key used by the TLS server(s) (do not share!)
- certs/ca_crt.txt A C string copy of CA.crt for easier reuse elsewhere
You can view the content of the certificates via:
$ openssl x509 -in certs/CA.crt -noout -text
$ openssl x509 -in certs/SERVER.crt -noout -text
HOSTNAME
--------
A consistent hostname must be used in your network layout, since the name will
be included in the generated certificates, and the TLS handshake will fail
if the hostname used by the servers and the value defined in the certificate(s)
don't match.
For this script, which generates the SERVER certificate that includes the
hostname, you can set the hostname value through several mechanism:
1. Via the '[hostname]' parameter when calling this script, i.e.:
$ ./setup-ca.sh myhostname.local
2. Setting the 'CAHOSTNAME' environment variable before running this script:
$ export CAHOSTNAME=myhostname.local
$ ./setup-ca.sh
3. Not doing anything, which will cause the script to evaluate the system
hostname via the 'hostname' command.
NOTE: 'localhost' is useful for testing, particularly if you are behind a NAT,
but won't allow access from a remote device. In order for this server to work
in that network topology, you'll need to set the hostname to a valid DNS name
that resolves to this host.
"
exit
fi
# Check for previous build artifacts
if [ -f certs/CA.crt ] || [ -f certs/CA.key ] || \
[ -f certs/SERVER.crt ] || [ -f certs/SERVER.key ];
then
echo "Server/CA certificates seem to already be present."
echo ""
echo "Run 'rm -rf certs' to remove them all first."
echo ""
exit 1
fi
if [ -f CADB.db ];
then
echo "Server/CA database (CADB.db) seem to already be present."
echo ""
echo "Run 'rm CADB.db' to delete it first."
echo ""
exit 1
fi
# Resolve hostname
if [ $# -eq 1 ]
then
# Use command line parameter for hostname value if present
HOSTNAME=$1
else
# Check for CAHOSTNAME env variable, default to 'hostname' cmd if undefined
HOSTNAME=${CAHOSTNAME:-$(hostname)}
fi
# Setup the Certificate Authority and server certificates. In
# general, this should be run once, to create these initial
# certificates, for development.
mkdir -p certs
# Build the application.
go build -o liteboot || exit 1
# The certificate authority requires a key to sign certificates,
# which can be generated by the app.
./liteboot cakey generate
# Extract the CA certificate as a C string for inclusion in the demo app.
sed 's/.*/"&\\r\\n"/' certs/CA.crt > certs/ca_crt.txt
# The CA key is not extracted, as the device should have no access to this.
# The HTTP server requires a private key for TLS.
openssl ecparam -name secp256r1 -genkey -out certs/SERVER.key
# Generate an X.509 certificate for use by the server. The clients
# can verify this by having the CA.crt available, and use this to
# ensure we are talking to the right server.
openssl req -new -sha256 -key certs/SERVER.key \
-out certs/SERVER.csr \
-subj "/O=Linaro, LTD/CN=$HOSTNAME"
# Create a config snippet to add proper extensions to this key.
echo "subjectKeyIdentifier=hash" > exts$$.ext
echo "authorityKeyIdentifier=keyid,issuer" >> exts$$.ext
echo "basicConstraints = critical, CA:FALSE" >> exts$$.ext
echo "keyUsage = critical, digitalSignature" >> exts$$.ext
echo "extendedKeyUsage = serverAuth" >> exts$$.ext
echo "subjectAltName = DNS:$HOSTNAME" >> exts$$.ext
# Sign this with the CA.
openssl x509 -req -sha256 \
-CA certs/CA.crt \
-CAkey certs/CA.key \
-days 3560 \
-CAcreateserial \
-CAserial certs/CA.srl \
-in certs/SERVER.csr \
-out certs/SERVER.crt \
-extfile exts$$.ext
rm certs/SERVER.csr
rm exts$$.ext
# This certificate can be viewed with
# openssl x509 -in certs/SERVER.crt -noout -text
# **NOTE**: Certain values are hard-coded in `liteboot` when
# generating the CA certificate. This utility may be extended to
# expose those values in the future, but at the moment the hard-coded
# values are sufficient for the proof-of-concept nature of this app.