]>
git.proxmox.com Git - mirror_ovs.git/blob - utilities/ovs-pki.in
3 # Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at:
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
25 log
='@LOGDIR@/ovs-pki.log'
29 # OS-specific compatibility routines
31 FreeBSD|NetBSD|Darwin
)
34 stat
-r "$1" |
awk '{print $10}'
61 # This option-parsing mechanism borrowed from a Autoconf-generated
62 # configure script under the following license:
64 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
65 # 2002, 2003, 2004, 2005, 2006, 2009 Free Software Foundation, Inc.
66 # This configure script is free software; the Free Software Foundation
67 # gives unlimited permission to copy, distribute and modify it.
69 # If the previous option needs an argument, assign it.
70 if test -n "$prev"; then
76 *=*) optarg
=`expr "X$option" : '[^=]*=\(.*\)'` ;;
80 case $dashdash$option in
85 ovs-pki, for managing a simple OpenFlow public key infrastructure
86 usage: $0 [OPTION...] COMMAND [ARG...]
88 The valid stand-alone commands and their arguments are:
89 init Initialize the PKI
90 req NAME Create new private key and certificate request
91 named NAME-privkey.pem and NAME-req.pem, resp.
92 sign NAME [TYPE] Sign switch certificate request NAME-req.pem,
93 producing certificate NAME-cert.pem
94 req+sign NAME [TYPE] Combine the above two steps, producing all three files.
95 verify NAME [TYPE] Checks that NAME-cert.pem is a valid TYPE certificate
96 fingerprint FILE Prints the fingerprint for FILE
97 self-sign NAME Sign NAME-req.pem with NAME-privkey.pem,
98 producing self-signed certificate NAME-cert.pem
99 Each TYPE above is a certificate type: 'switch' (default) or 'controller'.
101 Options for 'init', 'req', and 'req+sign' only:
102 -k, --key=rsa|dsa Type of keys to use (default: rsa)
103 -B, --bits=NBITS Number of bits in keys (default: 2048). For DSA keys,
104 this has an effect only on 'init'.
105 -D, --dsaparam=FILE File with DSA parameters (DSA only)
106 (default: dsaparam.pem within PKI directory)
107 Options for use with the 'sign' command:
108 -b, --batch Skip fingerprint verification
109 Options that apply to any command:
110 -d, --dir=DIR Directory where the PKI is located
112 -f, --force Continue even if file or directory already exists
113 -l, --log=FILE Log openssl output to FILE (default: ovs-log.log)
114 -u, --unique NAME is unique (don't append UUID/date)
115 -h, --help Print this usage message.
116 -V, --version Display version information.
121 echo "ovs-pki (Open vSwitch) @VERSION@"
164 echo "unrecognized option $option" >&2
168 if test -z "$command"; then
170 elif test -z "${arg1+set}"; then
172 elif test -z "${arg2+set}"; then
175 echo "$option: only two arguments may be specified" >&2
182 if test -n "$prev"; then
183 option
=--`echo $prev | sed 's/_/-/g'`
184 { echo "$as_me: error: missing argument to $option" >&2
185 { (exit 1); exit 1; }; }
187 if test -z "$command"; then
188 echo "$0: missing command name; use --help for help" >&2
191 if test "$keytype" != rsa
&& test "$keytype" != dsa
; then
192 echo "$0: argument to -k or --key must be rsa or dsa" >&2
195 if test "$bits" -lt 1024; then
196 echo "$0: argument to -B or --bits must be at least 1024" >&2
199 if test -z "$dsaparam"; then
200 dsaparam
=$pkidir/dsaparam.pem
207 logdir
=$
(dirname "$log")
208 if test ! -d "$logdir"; then
209 mkdir
-p -m750 "$logdir" 2>/dev
/null || true
210 if test ! -d "$logdir"; then
211 echo "$0: log directory $logdir does not exist and cannot be created" >&2
216 if test "$command" = "init"; then
217 if test -e "$pkidir" && test "$force" != "yes"; then
218 echo "$0: $pkidir already exists and --force not specified" >&2
222 if test ! -d "$pkidir"; then
228 if test $keytype = dsa
&& test ! -e dsaparam.pem
; then
229 echo "Generating DSA parameters, please wait..." >&2
230 openssl dsaparam
-out dsaparam.pem
$bits 1>&3 2>&3
233 # Get the current date to add some uniqueness to this certificate
234 curr_date
=`date +"%Y %b %d %T"`
237 for ca
in controllerca switchca
; do
238 echo "Creating $ca..." >&2
243 mkdir
-p certs crl newcerts
244 mkdir
-p -m 0700 private
246 test -e crlnumber ||
echo 01 > crlnumber
247 test -e serial ||
echo 01 > serial
249 # Put DSA parameters in directory.
250 if test $keytype = dsa
&& test ! -e dsaparam.pem
; then
254 # Write CA configuration file.
255 if test ! -e ca.cnf
; then
256 sed "s/@ca@/$ca/g;s/@curr_date@/$curr_date/g" > ca.cnf
<<'EOF'
259 distinguished_name = req_distinguished_name
261 [ req_distinguished_name ]
267 CN = OVS @ca@ CA Certificate (@curr_date@)
274 database = $dir/index.txt # index file.
275 new_certs_dir = $dir/newcerts # new certs dir
276 certificate = $dir/cacert.pem # The CA cert
277 serial = $dir/serial # serial no file
278 private_key = $dir/private/cakey.pem# CA private key
279 RANDFILE = $dir/private/.rand # random number file
280 default_days = 3650 # how long to certify for
281 default_crl_days= 30 # how long before next CRL
282 default_md = sha512 # message digest to use
283 policy = policy # default policy
284 email_in_dn = no # Don't add the email into cert DN
285 name_opt = ca_default # Subject name display option
286 cert_opt = ca_default # Certificate display option
287 copy_extensions = copy # Copy extensions from request
288 unique_subject = no # Allow certs with duplicate subjects
292 countryName = optional
293 stateOrProvinceName = optional
294 organizationName = match
295 organizationalUnitName = optional
296 commonName = supplied
297 emailAddress = optional
299 # For the x509v3 extension
301 basicConstraints=CA:true
304 basicConstraints=CA:false
308 # Create certificate authority.
309 if test $keytype = dsa
; then
310 newkey
=dsa
:dsaparam.pem
314 openssl req
-config ca.cnf
-nodes \
315 -newkey $newkey -keyout private
/cakey.pem
-out careq.pem \
317 openssl ca
-config ca.cnf
-create_serial \
318 -extensions ca_cert
-out cacert.pem \
319 -days 3650 -batch -keyfile private
/cakey.pem
-selfsign \
320 -infiles careq.pem
1>&3 2>&3
321 chmod 0700 private
/cakey.pem
329 if test -z "$arg1" ||
test -n "$arg2"; then
330 echo "$0: $command must have exactly one argument; use --help for help" >&2
336 if test -z "$arg1"; then
337 echo "$0: $command must have one or two arguments; use --help for help" >&2
343 if test -e "$1" && test "$force" != "yes"; then
344 echo "$0: $1 already exists and --force not supplied" >&2
350 TMP
=/tmp
/ovs-pki.tmp$$
359 date=$
(file_mod_date
"$file")
360 if grep -e '-BEGIN CERTIFICATE-' "$file" > /dev
/null
; then
361 fingerprint
=$
(openssl x509
-noout -in "$file" -fingerprint |
362 sed 's/SHA1 Fingerprint=//' |
tr -d ':')
364 fingerprint
=$
(sha1sum "$file" |
awk '{print $1}')
366 printf "$name\\t$date\\n"
369 printf "\\t(correct fingerprint in filename)\\n"
372 printf "\\tfingerprint $fingerprint\\n"
377 verify_fingerprint
() {
379 if test $batch != yes; then
380 echo "Does fingerprint match? (yes/no)"
382 if test "$answer" != yes; then
383 echo "Match failure, aborting" >&2
390 if test x
= x
"$1"; then
392 elif test "$1" = switch ||
test "$1" = controller
; then
395 echo "$0: type argument must be 'switch' or 'controller'" >&2
401 number
=$
(echo $1 |
sed 's/^\([0-9]\+\)\([[:alpha:]]\+\)/\1/')
402 unit
=$
(echo $1 |
sed 's/^\([0-9]\+\)\([[:alpha:]]\+\)/\2/')
417 echo "$1: age not in the form Ns, Nmin, Nh, Nday (e.g. 1day)" >&2
421 echo $
(($number * $factor))
425 if test ! -e "$1"; then
426 echo "$0: $1 does not exist" >&2
431 pkidir_must_exist
() {
432 if test ! -e "$pkidir"; then
433 echo "$0: $pkidir does not exist (need to run 'init' or use '--dir'?)" >&2
435 elif test ! -d "$pkidir"; then
436 echo "$0: $pkidir is not a directory" >&2
442 must_not_exist
"$arg1-privkey.pem"
443 must_not_exist
"$arg1-req.pem"
445 if test $unique_name != yes; then
446 # Use uuidgen or date to create unique subject DNs.
447 unique
=`(uuidgen) 2>/dev/null` || unique
=`date +"%Y %b %d %T"`
448 cn
="$arg1 id:$unique"
452 cat > "$TMP/req.cnf" <<EOF
455 distinguished_name = req_distinguished_name
456 req_extensions = v3_req
458 [ req_distinguished_name ]
463 OU = Open vSwitch certifier
467 subjectAltName = DNS:$cn
469 if test $keytype = rsa
; then
470 (umask 077 && openssl genrsa
-out "$1-privkey.pem" $bits) 1>&3 2>&3 \
473 must_exist
"$dsaparam"
474 (umask 077 && openssl gendsa
-out "$1-privkey.pem" "$dsaparam") \
477 openssl req
-config "$TMP/req.cnf" -new -text \
478 -key "$1-privkey.pem" -out "$1-req.pem" 1>&3 2>&3
491 request_file
="`pwd`/$1"
495 (cd "$pkidir/${type}ca" &&
496 openssl ca
-config ca.cnf
-extensions usr_cert
-batch -in "$request_file") \
503 if test "$files" != "$1"; then
509 if test "$command" = req
; then
513 fingerprint
"$arg1-req.pem"
514 elif test "$command" = sign
; then
517 verify_fingerprint
"$arg1-req.pem"
519 sign_request
"$arg1-req.pem" "$arg1-cert.pem"
520 elif test "$command" = req
+sign
; then
526 sign_request
"$arg1-req.pem" "$arg1-cert.pem"
527 fingerprint
"$arg1-req.pem"
528 elif test "$command" = verify
; then
530 must_exist
"$arg1-cert.pem"
534 openssl verify
-CAfile "$pkidir/${type}ca/cacert.pem" "$arg1-cert.pem"
535 elif test "$command" = fingerprint
; then
539 elif test "$command" = self-sign
; then
541 must_exist
"$arg1-req.pem"
542 must_exist
"$arg1-privkey.pem"
543 must_not_exist
"$arg1-cert.pem"
545 cat > "$TMP/v3.ext" <<EOF
546 subjectAltName = DNS:$arg1
549 # Create both the private key and certificate with restricted permissions.
551 openssl x509
-in "$arg1-req.pem" -out "$arg1-cert.pem.tmp" \
552 -signkey "$arg1-privkey.pem" -req -days 3650 -text \
553 -extfile $TMP/v3.ext
) 2>&3 ||
exit $?
555 # Reset the permissions on the certificate to the user's default.
556 cat "$arg1-cert.pem.tmp" > "$arg1-cert.pem"
557 rm -f "$arg1-cert.pem.tmp"
559 echo "$0: $command command unknown; use --help for help" >&2