From d012fea24ba79e4dd789c814bef46c96301c7e82 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 16 Sep 2008 16:02:30 -0700 Subject: [PATCH] Use RSA instead of DSA by default for the OpenFlow PKI. --- utilities/ofp-pki.8.in | 124 ++++++++++++++++++++++++++++++----------- utilities/ofp-pki.in | 107 ++++++++++++++++++++++++----------- 2 files changed, 167 insertions(+), 64 deletions(-) diff --git a/utilities/ofp-pki.8.in b/utilities/ofp-pki.8.in index 3e0aaeec..36803473 100644 --- a/utilities/ofp-pki.8.in +++ b/utilities/ofp-pki.8.in @@ -6,7 +6,7 @@ ofp\-pki \- OpenFlow public key infrastructure management utility .SH SYNOPSIS \fBofp\-pki\fR [\fIOPTIONS\fR] \fICOMMAND\fR [\fIARGS\fR] .sp -Stand-alone commands with their arguments: +Stand\-alone commands with their arguments: .br \fBofp\-pki\fR \fBinit\fR .br @@ -39,7 +39,16 @@ Each \fITYPE\fR above is a certificate type, either \fBswitch\fR .sp The available options are: .br -[\fB-d\fR \fIDIR\fR | \fB--dir=\fR\fIDIR\fR] [\fB-f\fR | \fB--force\fR] [\fB-b\fR | \fB--batch\fR] [\fB-l\fR \fIFILE\fR | \fB--log=\fIFILE\fR] [\fB-h\fR | \fB--help\fR] +[\fB\-k\fR \fItype\fR | \fB\-\^\-key=\fItype\fR] +[\fB\-B\fR \fInbits\fR | \fB\-\^\-bits=\fInbits\fR] +[\fB\-D\fR \fIfile\fR | \fB\-\^\-dsaparam=\fIfile\fR] +[\fB\-b\fR | \fB\-\^\-batch\fR] +[\fB\-f\fR | \fB\-\^\-force\fR] +[\fB\-d\fR \fIdir\fR | \fB\-\^\-dir=\fR\fIdir\fR] +[\fB\-l\fR \fIfile\fR | \fB\-\^\-log=\fIfile\fR] +[\fB\-h\fR | \fB\-\^\-help\fR] +.br +Some options do not apply to every command. .SH DESCRIPTION The \fBofp\-pki\fR program sets up and manages a public key @@ -62,13 +71,21 @@ Initializes a new PKI (by default in directory \fB@pkidir@\fR) and populates it with a pair of certificate authorities for controllers and switches. -This command should ideally be run on a high-security machine separate +This command should ideally be run on a high\-security machine separate from any OpenFlow controller or switch, called the CA machine. The files \fBpki/controllerca/cacert.pem\fR and \fBpki/switchca/cacert.pem\fR that it produces will need to be copied over to the OpenFlow switches and controllers, respectively. Their contents may safely be made public. +By default, \fBofp\-pki\fR generates 2048\-bit RSA keys. The \fB\-B\fR +or \fB\-\^\-bits\fR option (see below) may be used to override the key +length. The \fB\-k dsa\fR or \fB\-\^\-key=dsa\fR option may be used to use +DSA in place of RSA. If DSA is selected, the \fBdsaparam.pem\fR file +generated in the new PKI hierarchy must be copied to any machine on +which the \fBreq\fR command (see below) will be executed. Its +contents may safely be made public. + Other files generated by \fBinit\fR may remain on the CA machine. The files \fBpki/controllerca/private/cakey.pem\fR and \fBpki/switchca/private/cakey.pem\fR have particularly sensitive @@ -76,27 +93,40 @@ contents that should not be exposed. .TP \fBreq\fR \fINAME\fR -Generates a new private key named \fINAME\fR\fB-privkey.pem\fR and -corresponding certificate request named \fINAME\fR\fB-req.pem\fR. +Generates a new private key named \fINAME\fR\fB\-privkey.pem\fR and +corresponding certificate request named \fINAME\fR\fB\-req.pem\fR. The private key can be intended for use by a switch or a controller. This command should ideally be run on the switch or controller that will use the private key to identify itself. The file -\fINAME\fR\fB-req.pem\fR must be copied to the CA machine for signing +\fINAME\fR\fB\-req.pem\fR must be copied to the CA machine for signing with the \fBsign\fR command (below). This command will output a fingerprint to stdout as its final step. Write down the fingerprint and take it to the CA machine before continuing with the \fBsign\fR step. -\fINAME\fR\fB-privkey.pem\fR has sensitive contents that should not be -exposed. \fINAME\fR\fB-req.pem\fR may be safely made public. +When RSA keys are in use (as is the default), \fBreq\fR, unlike the +rest of \fBofp\-pki\fR's commands, does not need access to a PKI +hierarchy created by \fBofp\-pki init\fR. The \fB\-B\fR or +\fB\-\^\-bits\fR option (see below) may be used to specify the number of +bits in the generated RSA key. + +When DSA keys are used (as specified with \fB\-\^\-key=dsa\fR), \fBreq\fR +needs access to the \fBdsaparam.pem\fR file created as part of the PKI +hierarchy (but not to other files in that tree). By default, +\fBofp\-pki\fR looks for this file in \fB@pkidir@/dsaparam.pem\fR, but +the \fB\-D\fR or \fB\-\^\-dsaparam\fR option (see below) may be used to +specify an alternate location. + +\fINAME\fR\fB\-privkey.pem\fR has sensitive contents that should not be +exposed. \fINAME\fR\fB\-req.pem\fR may be safely made public. .TP \fBsign\fR \fINAME\fR [\fITYPE\fR] -Signs the certificate request named \fINAME\fR\fB-req.pem\fR that was +Signs the certificate request named \fINAME\fR\fB\-req.pem\fR that was produced in the previous step, producing a certificate named -\fINAME\fR\fB-cert.pem\fR. \fITYPE\fR, either \fBswitch\fR (default) or +\fINAME\fR\fB\-cert.pem\fR. \fITYPE\fR, either \fBswitch\fR (default) or \fBcontroller\fR, indicates the use for which the key is being certified. @@ -105,10 +135,10 @@ This command must be run on the CA machine. The command will output a fingerprint to stdout and request that you verify that it is the same fingerprint output by the \fBreq\fR command. This ensures that the request being signed is the same one -produced by \fBreq\fR. (The \fB-b\fR or \fB--batch\fR option +produced by \fBreq\fR. (The \fB\-b\fR or \fB\-\^\-batch\fR option suppresses the verification step.) -The file \fINAME\fR\fB-cert.pem\fR will need to be copied back to the +The file \fINAME\fR\fB\-cert.pem\fR will need to be copied back to the switch or controller for which it is intended. Its contents may safely be made public. @@ -116,9 +146,9 @@ safely be made public. \fBreq+sign\fR \fINAME\fR [\fITYPE\fR] Combines the \fBreq\fR and \fBsign\fR commands into a single step, outputting all the files produced by each. The -\fINAME\fR\fB-privkey.pem\fR and \fINAME\fR\fB-cert.pem\fR files must +\fINAME\fR\fB\-privkey.pem\fR and \fINAME\fR\fB\-cert.pem\fR files must be copied securely to the switch or controller. -\fINAME\fR\fB-privkey.pem\fR has sensitive contents and must not be +\fINAME\fR\fB\-privkey.pem\fR has sensitive contents and must not be exposed in transit. Afterward, it should be deleted from the CA machine. @@ -129,23 +159,23 @@ key. However, it is also more convenient. .TP \fBverify\fR \fINAME\fR [\fITYPE\fR] -Verifies that \fINAME\fR\fB-cert.pem\fR is a valid certificate for the +Verifies that \fINAME\fR\fB\-cert.pem\fR is a valid certificate for the given \fITYPE\fR of use, either \fBswitch\fR (default) or \fBcontroller\fR. If the certificate is valid for this use, it prints -the message ``\fINAME\fR\fB-cert.pem\fR: OK''; otherwise, it prints an +the message ``\fINAME\fR\fB\-cert.pem\fR: OK''; otherwise, it prints an error message. .TP \fBofp\-pki\fR \fBfingerprint\fR \fIFILE\fR Prints the fingerprint for \fIFILE\fR. If \fIFILE\fR is a -certificate, then this is the SHA-1 digest of the DER encoded version -of the certificate; otherwise, it is the SHA-1 digest of the entire +certificate, then this is the SHA\-1 digest of the DER encoded version +of the certificate; otherwise, it is the SHA\-1 digest of the entire file. .SH "ONLINE COMMANDS" An OpenFlow PKI can be administered online, in conjunction with -.BR ofp-pki-cgi (8) +.BR ofp\-pki\-cgi (8) and a web server such as Apache: .IP \(bu @@ -160,7 +190,7 @@ controllers and switches to be uploaded into the \fBpki/controllerca/incoming\fR and \fBpki/switchca/incoming\fR directories, respectively. Uploaded certificate requests are stored in those directories under names of the form -\fIFINGERPRINT\fB-req.pem\fR, which \fIFINGERPRINT\fR is the SHA-1 +\fIFINGERPRINT\fB\-req.pem\fR, which \fIFINGERPRINT\fR is the SHA\-1 hash of the file. .IP \(bu @@ -204,7 +234,7 @@ the user to type fewer characters, not to match multiple certificate requests. The command will output a fingerprint to stdout and request that you -verify that it is correct. (The \fB-b\fR or \fB--batch\fR option +verify that it is correct. (The \fB\-b\fR or \fB\-\^\-batch\fR option suppresses the verification step.) .TP @@ -223,34 +253,62 @@ older than \fIAGE\fR, which must in one of the forms \fIN\fBs\fR, .SH OPTIONS .TP -[\fB-d\fR \fIDIR\fR | \fB--dir=\fR\fIDIR\fR] +\fB\-k\fR \fItype\fR | \fB\-\^\-key=\fItype\fR +For the \fBinit\fR command, sets the public key algorithm to use for +the new PKI hierarchy. For the \fBreq\fR and \fBreq+sign\fR commands, +sets the public key algorithm to use for the key to be generated, +which must match the value specified on \fBinit\fR. With other +commands, the value has no effect. + +The \fItype\fR may be \fBrsa\fR (the default) or \fBdsa\fR. + +.TP +\fB\-B\fR \fInbits\fR | \fB\-\^\-bits=\fInbits\fR +Sets the number of bits in the key to be generated. When RSA keys are +in use, this option affects only the \fBinit\fR, \fBreq\fR, and +\fBreq+sign\fR commands, and the same value should be given each time. +With DSA keys are in use, this option affects only the \fBinit\fR +command. + +The value must be at least 1024. The default is 2048. + +.TP +\fB\-D\fR \fIfile\fR | \fB\-\^\-dsaparam=\fIfile\fR +Specifies an alternate location for the \fBdsaparam.pem\fR file +required by the \fBreq\fR and \fBreq+sign\fR commands. This option +affects only these commands, and only when DSA keys are used. + +The default is \fBdsaparam.pem\fR under the PKI hierarchy. + +.TP +\fB\-b\fR | \fB\-\^\-batch\fR +Suppresses the interactive verification of fingerprints that the +\fBsign\fR and \fBapprove\fR commands by default require. + +.TP +\fB\-d\fR \fIdir\fR | \fB\-\^\-dir=\fR\fIdir\fR Specifies the location of the PKI hierarchy to be used or created by the command (default: \fB@pkidir@\fR). All commands, except \fBreq\fR, need access to a PKI hierarchy. .TP -[\fB-f\fR | \fB--force\fR] +\fB\-f\fR | \fB\-\^\-force\fR By default, \fBofp\-pki\fR will not overwrite existing files or directories. This option overrides this behavior. .TP -[\fB-b\fR | \fB--batch\fR] -Suppresses the interactive verification of fingerprints that the -\fBsign\fR command by default requires. - -.TP -[\fB-l\fR \fIFILE\fR | \fB--log=\fIFILE\fR] -Sets the log file to \fIFILE\fR. If \fIFILE\fR starts with \fB/\fR, +\fB\-l\fR \fIfile\fR | \fB\-\^\-log=\fIfile\fR +Sets the log file to \fIfile\fR. If \fIfile\fR starts with \fB/\fR, it is taken as an absolute path; otherwise it is relative to the PKI -hierarchy. Default: \fBofp-pki.log\fR. +hierarchy. Default: \fBofp\-pki.log\fR. .TP -[\fB-h\fR | \fB--help\fR] +\fB\-h\fR | \fB\-\^\-help\fR Prints a help usage message and exits. .SH "SEE ALSO" -.BR ofp-pki-cgi (8), +.BR ofp\-pki\-cgi (8), .BR dpctl (8), .BR switch (8), .BR secchan (8), diff --git a/utilities/ofp-pki.in b/utilities/ofp-pki.in index ca927c02..6f227d63 100755 --- a/utilities/ofp-pki.in +++ b/utilities/ofp-pki.in @@ -6,6 +6,8 @@ prev= force=no batch=no log=ofp-pki.log +keytype=rsa +bits=2048 for option; do # This option-parsing mechanism borrowed from a Autoconf-generated # configure script under the following license: @@ -59,22 +61,47 @@ The following additional commands manage an online PKI: Each TYPE above is a certificate type: 'switch' (default) or 'controller'. -The valid OPTIONS are: +Options for 'init', 'req', and 'req+sign' only: + -k, --key=rsa|dsa Type of keys to use (default: rsa) + -B, --bits=NBITS Number of bits in keys (default: 2048). For DSA keys, + this has an effect only on 'init'. + -D, --dsaparam=FILE File with DSA parameters (DSA only) + (default: dsaparam.pem within PKI directory) +Options for use with the 'sign' and 'approve' commands: + -b, --batch Skip fingerprint verification +Options that apply to any command: -d, --dir=DIR Directory where the PKI is located (default: $pkidir) -f, --force Continue even if file or directory already exists - -b, --batch Skip fingerprint verification -l, --log=FILE Log openssl output to FILE (default: ofp-log.log) -h, --help Print this usage message. EOF exit 0 ;; - --d*=*) + --di*=*) pkidir=$optarg ;; - --d*|-d) + --di*|-d) prev=pkidir ;; + --k*=*) + keytype=$optarg + ;; + --k*|-k) + prev=keytype + ;; + --bi*=*) + bits=$optarg + ;; + --bi*|-B) + prev=bits + ;; + --ds*=*) + dsaparam=$optarg + ;; + --ds*|-D) + prev=dsaparam + ;; --l*=*) log=$optarg ;; @@ -84,7 +111,7 @@ EOF --force|-f) force=yes ;; - --batch|-b) + --ba*|-b) batch=yes ;; -*) @@ -115,10 +142,21 @@ if test -z "$command"; then echo "$0: missing command name; use --help for help" >&2 exit 1 fi +if test "$keytype" != rsa && test "$keytype" != dsa; then + echo "$0: argument to -k or --key must be rsa or dsa" + exit 1 +fi +if test "$bits" -lt 1024; then + echo "$0: argument to -B or --bits must be at least 1024" + exit 1 +fi +if test -z "$dsaparam"; then + dsaparam=$pkidir/dsaparam.pem +fi if test "$command" = "init"; then if test -e "$pkidir" && test "$force" != "yes"; then - echo "$0: $pkidir already exists" >&2 + echo "$0: $pkidir already exists and --force not specified" >&2 exit 1 fi @@ -128,26 +166,9 @@ if test "$command" = "init"; then cd "$pkidir" exec 3>>$log - if test ! -e dsaparam.pem; then + if test $keytype = dsa && test ! -e dsaparam.pem; then echo "Generating DSA parameters, please wait..." >&2 - openssl dsaparam -out dsaparam.pem 2048 1>&3 2>&3 - fi - - # Create the request configuration. - if test ! -e req.cnf; then - cat > req.cnf <&3 2>&3 fi # Create the CAs. @@ -165,7 +186,7 @@ EOF test -e serial || echo 01 > serial # Put DSA parameters in directory. - if test ! -e dsaparam.pem; then + if test $keytype = dsa && test ! -e dsaparam.pem; then cp ../dsaparam.pem . fi @@ -216,8 +237,13 @@ EOF fi # Create certificate authority. + if test $keytype = dsa; then + newkey=dsa:dsaparam.pem + else + newkey=rsa:$bits + fi openssl req -config ca.cnf -nodes \ - -newkey dsa:dsaparam.pem -keyout private/cakey.pem -out careq.pem \ + -newkey $newkey -keyout private/cakey.pem -out careq.pem \ 1>&3 2>&3 openssl ca -config ca.cnf -create_serial -out cacert.pem \ -days 1095 -batch -keyfile private/cakey.pem -selfsign \ @@ -386,10 +412,28 @@ pkidir_must_exist() { make_request() { must_not_exist "$arg1-privkey.pem" must_not_exist "$arg1-req.pem" - pkidir_must_exist - openssl req -config "$pkidir/req.cnf" -text -nodes \ - -newkey "dsa:$pkidir/dsaparam.pem" -keyout "$1-privkey.pem" \ - -out "$1-req.pem" 1>&3 2>&3 + make_tmpdir + cat > "$TMP/req.cnf" <&3 2>&3 } sign_request() { @@ -434,6 +478,7 @@ elif test "$command" = req+sign; then one_or_two_args check_type "$arg2" + pkidir_must_exist make_request "$arg1" sign_request "$arg1-req.pem" "$arg1-cert.pem" fingerprint "$arg1-req.pem" -- 2.30.2