Merged revisions 294049 via svnmerge from
[asterisk/asterisk.git] / contrib / scripts / ast_tls_cert
1 #!/bin/sh -e
2 DEFAULT_ORG="Asterisk"
3 DEFAULT_CA_CN="Asterisk Private CA"
4 DEFAULT_CLIENT_CN="asterisk"
5 DEFAULT_SERVER_CN=`hostname -f`
6
7 # arguments
8 # $1 "ca" if we are to generate a CA cert
9 # $2 alternate config file name (for ca)
10 # $3 alternate common name
11 # $4 alternate org name
12 create_config () {
13         if [ "$1" = "ca" ]
14         then
15 castring="
16 [ext]
17 basicConstraints=CA:TRUE"
18         fi
19
20 cat > ${2:-"${CONFIG_FILE}"} << EOF
21 [req]
22 distinguished_name = req_distinguished_name
23 prompt = no
24
25 [req_distinguished_name]
26 CN=${3:-"${COMMON_NAME}"}
27 O=${4:-"${ORG_NAME}"}
28 ${castring}
29 EOF
30 }
31
32 create_ca () {
33         echo "Creating ${CAKEY}"
34         openssl genrsa -des3 -out ${CAKEY} 4096 > /dev/null
35         echo "Creating ${CACERT}"
36         openssl req -new -config ${CACFG} -x509 -days 365 -key ${CAKEY} -out ${CACERT} > /dev/null
37 }
38
39 create_cert () {
40         local base=${OUTPUT_DIR}/${OUTPUT_BASE}
41         echo "Creating ${base}.key"
42         openssl genrsa -out ${base}.key 1024 > /dev/null
43         echo "Creating signing request"
44         openssl req -batch -new -config ${CONFIG_FILE} -key ${base}.key -out ${base}.csr > /dev/null
45         echo "Creating ${base}.crt"
46         openssl x509 -req -days 365 -in ${base}.csr -CA ${CACERT} -CAkey ${CAKEY} -set_serial 01 -out ${base}.crt > /dev/null
47         echo "Combining key and crt into ${base}.pem"
48         cat ${base}.key > ${base}.pem
49         cat ${base}.crt >> ${base}.pem
50 }
51
52 usage () {
53 cat << EOF
54 This script is useful for quickly generating self-signed CA, server, and client
55 certificates for use with Asterisk. It is still recommended to obtain
56 certificates from a recognized Certificate Authority and to develop an
57 understanding how SSL certificates work. Real security is hard work.
58
59 OPTIONS:
60   -h  Show this message
61   -m  Type of cert "client" or "server". Defaults to server.
62   -f  Config filename (openssl config file format)
63   -c  CA cert filename (creates new CA cert/key as ca.crt/ca.key if not passed)
64   -k  CA key filename
65   -C  Common name (cert field)
66         This should be the fully qualified domain name or IP address for
67         the client or server. Make sure your certs have unique common
68         names.
69   -O  Org name (cert field)
70         An informational string (company name)
71   -o  Output filename base (defaults to asterisk) 
72   -d  Output directory (defaults to the current directory)
73
74 Example:
75
76 To create a CA and a server (pbx.mycompany.com) cert with output in /tmp:
77   ast_tls_cert -C pbx.mycompany.com -O "My Company" -d /tmp
78
79 This will create a CA cert and key as well as asterisk.pem and the the two
80 files that it is made from: asterisk.crt and asterisk.key. Copy asterisk.pem
81 and ca.crt somewhere (like /etc/asterisk) and set tlscertfile=/etc/asterisk.pem
82 and tlscafile=/etc/ca.crt. Since this is a self-signed key, many devices will
83 require you to import the ca.crt file as a trusted cert.
84
85 To create a client cert using the CA cert created by the example above:
86   ast_tls_cert -m client -c /tmp/ca.crt -k /tmp/ca.key -C phone1.mycompany.com \\
87     -O "My Company" -d /tmp -o joe_user
88
89 This will create client.crt/key/pem in /tmp. Use this if your device supports
90 a client certificate. Make sure that you have the ca.crt file set up as
91 a tlscafile in the necessary Asterisk configs. Make backups of all .key files
92 in case you need them later.
93 EOF
94 }
95
96 if ! type openssl >/dev/null 2>&1
97 then
98         echo "This script requires openssl to be in the path"
99         exit 1
100 fi
101
102 OUTPUT_BASE=asterisk # Our default cert basename
103 CERT_MODE=server
104 ORG_NAME=${DEFAULT_ORG}
105
106 while getopts "hf:c:k:o:d:m:C:O:" OPTION
107 do
108         case ${OPTION} in
109                 h)
110                         usage
111                         exit 1
112                         ;;
113                 f)
114                         CONFIG_FILE=${OPTARG}
115                         ;;
116                 c)
117                         CACERT=${OPTARG}
118                         ;;
119                 k)
120                         CAKEY=${OPTARG}
121                         ;;
122                 o)
123                         OUTPUT_BASE=${OPTARG}
124                         ;;
125                 d)
126                         OUTPUT_DIR=${OPTARG}
127                         ;;
128                 m)
129                         CERT_MODE=${OPTARG}
130                         ;;
131                 C)
132                         COMMON_NAME=${OPTARG}
133                         ;;
134                 O)
135                         ORG_NAME=${OPTARG}
136                         ;;
137                 ?)
138                         usage
139                         exit
140                         ;;
141         esac
142 done
143
144 if [ -z "${OUTPUT_DIR}" ]
145 then
146         OUTPUT_DIR=.
147 else
148         mkdir -p "${OUTPUT_DIR}"
149 fi
150
151 umask 177
152
153 case "${CERT_MODE}" in
154         server)
155                 COMMON_NAME=${COMMON_NAME:-"${DEFAULT_SERVER_CN}"}
156                 ;;
157         client)
158                 COMMON_NAME=${COMMON_NAME:-"${DEFAULT_CLIENT_CN}"}
159                 ;;
160         *)
161                 echo
162                 echo "Unknown mode. Exiting."
163                 exit 1
164                 ;;
165 esac
166
167 if [ -z "${CONFIG_FILE}" ]
168 then
169         CONFIG_FILE="${OUTPUT_DIR}/tmp.cfg"
170         echo
171         echo "No config file specified, creating '${CONFIG_FILE}'"
172         echo "You can use this config file to create additional certs without"
173         echo "re-entering the information for the fields in the certificate"
174         create_config
175 fi
176
177 if [ -z ${CACERT} ]
178 then
179         CAKEY=${OUTPUT_DIR}/ca.key
180         CACERT=${OUTPUT_DIR}/ca.crt
181         CACFG=${OUTPUT_DIR}/ca.cfg
182         create_config ca "${CACFG}" "${DEFAULT_CA_CN}" "${DEFAULT_CA_ORG}"
183         create_ca
184 fi
185
186 create_cert