/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk

« back to all changes in this revision

Viewing changes to mandos-keygen

  • Committer: Teddy Hogeborn
  • Date: 2008-08-29 05:53:59 UTC
  • Revision ID: teddy@fukt.bsnet.se-20080829055359-wkdasnyxtylmnxus
* mandos.xml (EXAMPLE): Replaced all occurences of command name with
                        "&COMMANDNAME;".

* plugins.d/password-prompt.c (main): Improved some documentation
                                      strings.  Do perror() of
                                      tcgetattr() fails.  Add debug
                                      output if interrupted by signal.
                                      Loop over write() instead of
                                      using fwrite() when outputting
                                      password.  Add debug output if
                                      getline() returns 0, unless it
                                      was caused by a signal.  Add
                                      exit status code to debug
                                      output.

* plugins.d/password-prompt.xml: Changed all single quotes to double
                                 quotes for consistency.  Removed
                                 <?xml-stylesheet>.
  (ENTITY TIMESTAMP): New.  Automatically updated by Emacs time-stamp
                      by using Emacs local variables.
  (/refentry/refentryinfo/title): Changed to "Mandos Manual".
  (/refentry/refentryinfo/productname): Changed to "Mandos".
  (/refentry/refentryinfo/date): New; set to "&TIMESTAMP;".
  (/refentry/refentryinfo/copyright): Split copyright holders.
  (/refentry/refnamediv/refpurpose): Improved wording.
  (SYNOPSIS): Fix to use correct markup.  Add short options.
  (DESCRIPTION, OPTIONS): Improved wording.
  (OPTIONS): Improved wording.  Use more correct markup.  Document
             short options.
  (EXIT STATUS): Add text.
  (ENVIRONMENT): Document use of "cryptsource" and "crypttarget".
  (FILES): REMOVED.
  (BUGS): Add text.
  (EXAMPLE): Added some examples.
  (SECURITY): Added text.
  (SEE ALSO): Remove reference to mandos(8).  Add reference to
              crypttab(5).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#!/bin/sh -e
2
2
3
 
# Mandos key generator - create new keys for a Mandos client
4
 
5
 
# Copyright © 2008-2019 Teddy Hogeborn
6
 
# Copyright © 2008-2019 Björn Påhlsson
7
 
8
 
# This file is part of Mandos.
9
 
#
10
 
# Mandos is free software: you can redistribute it and/or modify it
11
 
# under the terms of the GNU General Public License as published by
 
3
# Mandos key generator - create a new OpenPGP key for a Mandos client
 
4
 
5
# Copyright © 2007-2008 Teddy Hogeborn & Björn Påhlsson
 
6
 
7
# This program is free software: you can redistribute it and/or modify
 
8
# it under the terms of the GNU General Public License as published by
12
9
# the Free Software Foundation, either version 3 of the License, or
13
10
# (at your option) any later version.
14
11
#
15
 
#     Mandos is distributed in the hope that it will be useful, but
16
 
#     WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
#     This program is distributed in the hope that it will be useful,
 
13
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
17
14
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
15
#     GNU General Public License for more details.
19
16
20
17
# You should have received a copy of the GNU General Public License
21
 
# along with Mandos.  If not, see <http://www.gnu.org/licenses/>.
22
 
23
 
# Contact the authors at <mandos@recompile.se>.
24
 
25
 
 
26
 
VERSION="1.8.4"
27
 
 
28
 
KEYDIR="/etc/keys/mandos"
29
 
KEYTYPE=RSA
30
 
KEYLENGTH=4096
31
 
SUBKEYTYPE=RSA
32
 
SUBKEYLENGTH=4096
33
 
KEYNAME="`hostname --fqdn 2>/dev/null || hostname`"
 
18
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
19
 
20
# Contact the authors at <mandos@fukt.bsnet.se>.
 
21
 
22
 
 
23
VERSION="1.0"
 
24
 
 
25
KEYDIR="/etc/mandos"
 
26
KEYTYPE=DSA
 
27
KEYLENGTH=2048
 
28
SUBKEYTYPE=ELG-E
 
29
SUBKEYLENGTH=2048
 
30
KEYNAME="`hostname --fqdn`"
34
31
KEYEMAIL=""
35
 
KEYCOMMENT=""
 
32
KEYCOMMENT="Mandos client key"
36
33
KEYEXPIRE=0
37
 
TLS_KEYTYPE=ed25519
38
34
FORCE=no
39
 
SSH=yes
40
35
KEYCOMMENT_ORIG="$KEYCOMMENT"
41
36
mode=keygen
42
37
 
43
 
if [ ! -d "$KEYDIR" ]; then
44
 
    KEYDIR="/etc/mandos/keys"
45
 
fi
46
 
 
47
38
# Parse options
48
 
TEMP=`getopt --options vhpF:d:t:l:s:L:n:e:c:x:T:fS \
49
 
    --longoptions version,help,password,passfile:,dir:,type:,length:,subtype:,sublength:,name:,email:,comment:,expire:,tls-keytype:,force,no-ssh \
 
39
TEMP=`getopt --options vhd:t:l:n:e:c:x:f \
 
40
    --longoptions version,help,password,dir:,type:,length:,subtype:,sublength:,name:,email:,comment:,expire:,force \
50
41
    --name "$0" -- "$@"`
51
42
 
52
43
help(){
53
 
basename="`basename "$0"`"
 
44
basename="`basename $0`"
54
45
cat <<EOF
55
46
Usage: $basename [ -v | --version ]
56
47
       $basename [ -h | --help ]
58
49
       $basename [ OPTIONS ]
59
50
   Encrypted password creation:
60
51
       $basename { -p | --password } [ --name NAME ] [ --dir DIR]
61
 
       $basename { -F | --passfile } FILE [ --name NAME ] [ --dir DIR]
62
52
 
63
53
Key creation options:
64
54
  -v, --version         Show program's version number and exit
65
55
  -h, --help            Show this help message and exit
66
56
  -d DIR, --dir DIR     Target directory for key files
67
 
  -t TYPE, --type TYPE  OpenPGP key type.  Default is RSA.
 
57
  -t TYPE, --type TYPE  Key type.  Default is DSA.
68
58
  -l BITS, --length BITS
69
 
                        OpenPGP key length in bits.  Default is 4096.
 
59
                        Key length in bits.  Default is 2048.
70
60
  -s TYPE, --subtype TYPE
71
 
                        OpenPGP subkey type.  Default is RSA.
 
61
                        Subkey type.  Default is ELG-E.
72
62
  -L BITS, --sublength BITS
73
 
                        OpenPGP subkey length in bits.  Default 4096.
 
63
                        Subkey length in bits.  Default is 2048.
74
64
  -n NAME, --name NAME  Name of key.  Default is the FQDN.
75
65
  -e ADDRESS, --email ADDRESS
76
 
                        Email address of OpenPGP key.  Default empty.
77
 
  -c TEXT, --comment TEXT
78
 
                        Comment field for OpenPGP key.  Default empty.
 
66
                        Email address of key.  Default is empty.
 
67
  -c COMMENT, --comment COMMENT
 
68
                        Comment field for key.  The default value is
 
69
                        "Mandos client key".
79
70
  -x TIME, --expire TIME
80
 
                        OpenPGP key expire time.  Default is none.
 
71
                        Key expire time.  Default is no expiration.
81
72
                        See gpg(1) for syntax.
82
 
  -T TYPE, --tls-keytype TYPE
83
 
                        TLS key type.  Default is ed25519.
84
 
  -f, --force           Force overwriting old key files.
 
73
  -f, --force           Force overwriting old keys.
85
74
 
86
75
Password creation options:
87
 
  -p, --password        Create an encrypted password using the key in
88
 
                        the key directory.  All options other than
89
 
                        --dir and --name are ignored.
90
 
  -F FILE, --passfile FILE
91
 
                        Encrypt a password from FILE using the key in
92
 
                        the key directory.  All options other than
93
 
                        --dir and --name are ignored.
94
 
  -S, --no-ssh          Don't get SSH key or set "checker" option.
 
76
  -p, --password        Create an encrypted password using the keys in
 
77
                        the key directory.  All options other than
 
78
                        --keydir and --name are ignored.
95
79
EOF
96
80
}
97
81
 
99
83
while :; do
100
84
    case "$1" in
101
85
        -p|--password) mode=password; shift;;
102
 
        -F|--passfile) mode=password; PASSFILE="$2"; shift 2;;
103
86
        -d|--dir) KEYDIR="$2"; shift 2;;
104
87
        -t|--type) KEYTYPE="$2"; shift 2;;
105
88
        -s|--subtype) SUBKEYTYPE="$2"; shift 2;;
109
92
        -e|--email) KEYEMAIL="$2"; shift 2;;
110
93
        -c|--comment) KEYCOMMENT="$2"; shift 2;;
111
94
        -x|--expire) KEYEXPIRE="$2"; shift 2;;
112
 
        -T|--tls-keytype) TLS_KEYTYPE="$2"; shift 2;;
113
95
        -f|--force) FORCE=yes; shift;;
114
 
        -S|--no-ssh) SSH=no; shift;;
115
96
        -v|--version) echo "$0 $VERSION"; exit;;
116
97
        -h|--help) help; exit;;
117
98
        --) shift; break;;
119
100
    esac
120
101
done
121
102
if [ "$#" -gt 0 ]; then
122
 
    echo "Unknown arguments: '$*'" >&2
 
103
    echo "Unknown arguments: '$@'" >&2
123
104
    exit 1
124
105
fi
125
106
 
126
107
SECKEYFILE="$KEYDIR/seckey.txt"
127
108
PUBKEYFILE="$KEYDIR/pubkey.txt"
128
 
TLS_PRIVKEYFILE="$KEYDIR/tls-privkey.pem"
129
 
TLS_PUBKEYFILE="$KEYDIR/tls-pubkey.pem"
130
109
 
131
110
# Check for some invalid values
132
 
if [ ! -d "$KEYDIR" ]; then
 
111
if [ -d "$KEYDIR" ]; then :; else
133
112
    echo "$KEYDIR not a directory" >&2
134
113
    exit 1
135
114
fi
136
 
if [ ! -r "$KEYDIR" ]; then
137
 
    echo "Directory $KEYDIR not readable" >&2
 
115
if [ -w "$KEYDIR" ]; then :; else
 
116
    echo "Directory $KEYDIR not writeable" >&2
 
117
    exit 1
 
118
fi
 
119
 
 
120
if [ "$mode" = password -a -e "$KEYDIR/trustdb.gpg.lock" ]; then
 
121
    echo "Key directory has locked trustdb; aborting." >&2
138
122
    exit 1
139
123
fi
140
124
 
141
125
if [ "$mode" = keygen ]; then
142
 
    if [ ! -w "$KEYDIR" ]; then
143
 
        echo "Directory $KEYDIR not writeable" >&2
144
 
        exit 1
145
 
    fi
146
126
    if [ -z "$KEYTYPE" ]; then
147
127
        echo "Empty key type" >&2
148
128
        exit 1
157
137
        echo "Invalid key length" >&2
158
138
        exit 1
159
139
    fi
160
 
    
 
140
 
161
141
    if [ -z "$KEYEXPIRE" ]; then
162
142
        echo "Empty key expiration" >&2
163
143
        exit 1
169
149
        [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|*) FORCE=0;;
170
150
    esac
171
151
    
172
 
    if { [ -e "$SECKEYFILE" ] || [ -e "$PUBKEYFILE" ] \
173
 
             || [ -e "$TLS_PRIVKEYFILE" ] \
174
 
             || [ -e "$TLS_PUBKEYFILE" ]; } \
 
152
    if { [ -e "$SECKEYFILE" ] || [ -e "$PUBKEYFILE" ]; } \
175
153
        && [ "$FORCE" -eq 0 ]; then
176
154
        echo "Refusing to overwrite old key files; use --force" >&2
177
155
        exit 1
184
162
    if [ -n "$KEYEMAIL" ]; then
185
163
        KEYEMAILLINE="Name-Email: $KEYEMAIL"
186
164
    fi
187
 
    
 
165
 
188
166
    # Create temporary gpg batch file
189
 
    BATCHFILE="`mktemp -t mandos-keygen-batch.XXXXXXXXXX`"
190
 
    TLS_PRIVKEYTMP="`mktemp -t mandos-keygen-privkey.XXXXXXXXXX`"
 
167
    BATCHFILE="`mktemp -t mandos-gpg-batch.XXXXXXXXXX`"
191
168
fi
192
169
 
193
170
if [ "$mode" = password ]; then
194
171
    # Create temporary encrypted password file
195
 
    SECFILE="`mktemp -t mandos-keygen-secfile.XXXXXXXXXX`"
196
 
fi
197
 
 
198
 
# Create temporary key ring directory
199
 
RINGDIR="`mktemp -d -t mandos-keygen-keyrings.XXXXXXXXXX`"
 
172
    SECFILE="`mktemp -t mandos-gpg-secfile.XXXXXXXXXX`"
 
173
fi
 
174
 
 
175
# Create temporary key rings
 
176
SECRING="`mktemp -t mandos-gpg-secring.XXXXXXXXXX`"
 
177
PUBRING="`mktemp -t mandos-gpg-pubring.XXXXXXXXXX`"
 
178
 
 
179
if [ "$mode" = password ]; then
 
180
    # If a trustdb.gpg file does not already exist, schedule it for
 
181
    # deletion when we are done.
 
182
    if ! [ -e "$KEYDIR/trustdb.gpg" ]; then
 
183
        TRUSTDB="$KEYDIR/trustdb.gpg"
 
184
    fi
 
185
fi
200
186
 
201
187
# Remove temporary files on exit
202
188
trap "
203
189
set +e; \
204
 
test -n \"$SECFILE\" && shred --remove \"$SECFILE\"; \
205
 
test -n \"$TLS_PRIVKEYTMP\" && shred --remove \"$TLS_PRIVKEYTMP\"; \
206
 
shred --remove \"$RINGDIR\"/sec* 2>/dev/null;
207
 
test -n \"$BATCHFILE\" && rm --force \"$BATCHFILE\"; \
208
 
rm --recursive --force \"$RINGDIR\";
209
 
tty --quiet && stty echo; \
 
190
rm --force $PUBRING ${PUBRING}~ $BATCHFILE $TRUSTDB; \
 
191
shred --remove $SECRING $SECFILE; \
 
192
stty echo; \
210
193
" EXIT
211
194
 
212
 
set -e
213
 
 
214
 
umask 077
 
195
umask 027
215
196
 
216
197
if [ "$mode" = keygen ]; then
217
198
    # Create batch file for GnuPG
218
199
    cat >"$BATCHFILE" <<-EOF
219
200
        Key-Type: $KEYTYPE
220
201
        Key-Length: $KEYLENGTH
221
 
        Key-Usage: sign,auth
 
202
        #Key-Usage: encrypt,sign,auth
222
203
        Subkey-Type: $SUBKEYTYPE
223
204
        Subkey-Length: $SUBKEYLENGTH
224
 
        Subkey-Usage: encrypt
 
205
        #Subkey-Usage: encrypt,sign,auth
225
206
        Name-Real: $KEYNAME
226
207
        $KEYCOMMENTLINE
227
208
        $KEYEMAILLINE
228
209
        Expire-Date: $KEYEXPIRE
229
210
        #Preferences: <string>
230
211
        #Handle: <no-spaces>
231
 
        #%pubring pubring.gpg
232
 
        #%secring secring.gpg
233
 
        %no-protection
 
212
        %pubring $PUBRING
 
213
        %secring $SECRING
234
214
        %commit
235
215
        EOF
236
216
    
237
 
    if tty --quiet; then
238
 
        cat <<-EOF
239
 
        Note: Due to entropy requirements, key generation could take
240
 
        anything from a few minutes to SEVERAL HOURS.  Please be
241
 
        patient and/or supply the system with more entropy if needed.
242
 
        EOF
243
 
        echo -n "Started: "
244
 
        date
245
 
    fi
246
 
 
247
 
    # Generate TLS private key
248
 
    if certtool --generate-privkey --password='' \
249
 
                --outfile "$TLS_PRIVKEYTMP" --sec-param ultra \
250
 
                --key-type="$TLS_KEYTYPE" --pkcs8 --no-text 2>/dev/null; then
251
 
        
252
 
        # Backup any old key files
253
 
        if cp --backup=numbered --force "$TLS_PRIVKEYFILE" "$TLS_PRIVKEYFILE" \
254
 
              2>/dev/null; then
255
 
            shred --remove "$TLS_PRIVKEYFILE" 2>/dev/null || :
256
 
        fi
257
 
        if cp --backup=numbered --force "$TLS_PUBKEYFILE" "$TLS_PUBKEYFILE" \
258
 
              2>/dev/null; then
259
 
            rm --force "$TLS_PUBKEYFILE"
260
 
        fi
261
 
        cp --archive "$TLS_PRIVKEYTMP" "$TLS_PRIVKEYFILE"
262
 
        shred --remove "$TLS_PRIVKEYTMP" 2>/dev/null || :
263
 
 
264
 
        ## TLS public key
265
 
 
266
 
        # First try certtool from GnuTLS
267
 
        if ! certtool --password='' --load-privkey="$TLS_PRIVKEYFILE" \
268
 
             --outfile="$TLS_PUBKEYFILE" --pubkey-info --no-text \
269
 
             2>/dev/null; then
270
 
            # Otherwise try OpenSSL
271
 
            if ! openssl pkey -in "$TLS_PRIVKEYFILE" \
272
 
                 -out "$TLS_PUBKEYFILE" -pubout; then
273
 
                rm --force "$TLS_PUBKEYFILE"
274
 
                # None of the commands succeded; give up
275
 
                return 1
276
 
            fi
277
 
        fi
278
 
    fi
279
 
    
280
 
    # Make sure trustdb.gpg exists;
281
 
    # this is a workaround for Debian bug #737128
282
 
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
283
 
        --homedir "$RINGDIR" \
284
 
        --import-ownertrust < /dev/null
285
217
    # Generate a new key in the key rings
286
 
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
287
 
        --homedir "$RINGDIR" --trust-model always \
 
218
    gpg --no-random-seed-file --quiet --batch --no-tty \
 
219
        --no-default-keyring --no-options --enable-dsa2 \
 
220
        --secret-keyring "$SECRING" --keyring "$PUBRING" \
288
221
        --gen-key "$BATCHFILE"
289
222
    rm --force "$BATCHFILE"
290
 
    
291
 
    if tty --quiet; then
292
 
        echo -n "Finished: "
293
 
        date
294
 
    fi
295
 
    
 
223
 
296
224
    # Backup any old key files
297
225
    if cp --backup=numbered --force "$SECKEYFILE" "$SECKEYFILE" \
298
226
        2>/dev/null; then
299
 
        shred --remove "$SECKEYFILE" 2>/dev/null || :
 
227
        shred --remove "$SECKEYFILE"
300
228
    fi
301
229
    if cp --backup=numbered --force "$PUBKEYFILE" "$PUBKEYFILE" \
302
230
        2>/dev/null; then
312
240
        FILECOMMENT="$FILECOMMENT <$KEYEMAIL>"
313
241
    fi
314
242
    
315
 
    # Export key from key rings to key files
316
 
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
317
 
        --homedir "$RINGDIR" --armor --export-options export-minimal \
318
 
        --comment "$FILECOMMENT" --output "$SECKEYFILE" \
319
 
        --export-secret-keys
320
 
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
321
 
        --homedir "$RINGDIR" --armor --export-options export-minimal \
322
 
        --comment "$FILECOMMENT" --output "$PUBKEYFILE" --export
 
243
    # Export keys from key rings to key files
 
244
    gpg --no-random-seed-file --quiet --batch --no-tty --armor \
 
245
        --no-default-keyring --no-options --enable-dsa2 \
 
246
        --secret-keyring "$SECRING" --keyring "$PUBRING" \
 
247
        --export-options export-minimal --comment "$FILECOMMENT" \
 
248
        --output "$SECKEYFILE" --export-secret-keys
 
249
    gpg --no-random-seed-file --quiet --batch --no-tty --armor \
 
250
        --no-default-keyring --no-options --enable-dsa2 \
 
251
        --secret-keyring "$SECRING" --keyring "$PUBRING" \
 
252
        --export-options export-minimal --comment "$FILECOMMENT" \
 
253
        --output "$PUBKEYFILE" --export
323
254
fi
324
255
 
325
256
if [ "$mode" = password ]; then
326
 
    
327
 
    # Make SSH be 0 or 1
328
 
    case "$SSH" in
329
 
        [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]) SSH=1;;
330
 
        [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|*) SSH=0;;
331
 
    esac
332
 
    
333
 
    if [ $SSH -eq 1 ]; then
334
 
        for ssh_keytype in ecdsa-sha2-nistp256 ed25519 rsa; do
335
 
            set +e
336
 
            ssh_fingerprint="`ssh-keyscan -t $ssh_keytype localhost 2>/dev/null`"
337
 
            err=$?
338
 
            set -e
339
 
            if [ $err -ne 0 ]; then
340
 
                ssh_fingerprint=""
341
 
                continue
342
 
            fi
343
 
            if [ -n "$ssh_fingerprint" ]; then
344
 
                ssh_fingerprint="${ssh_fingerprint#localhost }"
345
 
                break
346
 
            fi
347
 
        done
348
 
    fi
349
 
    
350
 
    # Import key into temporary key rings
351
 
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
352
 
        --homedir "$RINGDIR" --trust-model always --armor \
353
 
        --import "$SECKEYFILE"
354
 
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
355
 
        --homedir "$RINGDIR" --trust-model always --armor \
356
 
        --import "$PUBKEYFILE"
357
 
    
 
257
    # Import keys into temporary key rings
 
258
    gpg --no-random-seed-file --quiet --batch --no-tty --armor \
 
259
        --no-default-keyring --no-options --enable-dsa2 \
 
260
        --homedir "$KEYDIR" --no-permission-warning \
 
261
        --secret-keyring "$SECRING" --keyring "$PUBRING" \
 
262
        --trust-model always --import "$SECKEYFILE"
 
263
    gpg --no-random-seed-file --quiet --batch --no-tty --armor \
 
264
        --no-default-keyring --no-options --enable-dsa2 \
 
265
        --homedir "$KEYDIR" --no-permission-warning \
 
266
        --secret-keyring "$SECRING" --keyring "$PUBRING" \
 
267
        --trust-model always --import "$PUBKEYFILE"
 
268
 
358
269
    # Get fingerprint of key
359
 
    FINGERPRINT="`gpg --quiet --batch --no-tty --no-options \
360
 
        --enable-dsa2 --homedir "$RINGDIR" --trust-model always \
361
 
        --fingerprint --with-colons \
362
 
        | sed --quiet \
363
 
        --expression='/^fpr:/{s/^fpr:.*:\\([0-9A-Z]*\\):\$/\\1/p;q}'`"
 
270
    FINGERPRINT="`gpg --no-random-seed-file --quiet --batch --no-tty \
 
271
        --armor --no-default-keyring --no-options --enable-dsa2 \
 
272
        --homedir \"$KEYDIR\" --no-permission-warning \
 
273
        --secret-keyring \"$SECRING\" --keyring \"$PUBRING\" \
 
274
        --trust-model always --fingerprint --with-colons \
 
275
        | sed -n -e '/^fpr:/{s/^fpr:.*:\\([0-9A-Z]*\\):\$/\\1/p;q}'`"
364
276
    
365
277
    test -n "$FINGERPRINT"
366
278
    
367
 
    if [ -r "$TLS_PUBKEYFILE" ]; then
368
 
       KEY_ID="$(certtool --key-id --hash=sha256 \
369
 
                       --infile="$TLS_PUBKEYFILE" 2>/dev/null || :)"
370
 
 
371
 
       if [ -z "$KEY_ID" ]; then
372
 
           KEY_ID=$(openssl pkey -pubin -in "$TLS_PUBKEYFILE" \
373
 
                            -outform der \
374
 
                        | openssl sha256 \
375
 
                        | sed --expression='s/^.*[^[:xdigit:]]//')
376
 
       fi
377
 
       test -n "$KEY_ID"
378
 
    fi
379
 
    
380
279
    FILECOMMENT="Encrypted password for a Mandos client"
381
280
    
382
 
    while [ ! -s "$SECFILE" ]; do
383
 
        if [ -n "$PASSFILE" ]; then
384
 
            cat "$PASSFILE"
385
 
        else
386
 
            tty --quiet && stty -echo
387
 
            echo -n "Enter passphrase: " >/dev/tty
388
 
            read -r first
389
 
            tty --quiet && echo >&2
390
 
            echo -n "Repeat passphrase: " >/dev/tty
391
 
            read -r second
392
 
            if tty --quiet; then
393
 
                echo >&2
394
 
                stty echo
395
 
            fi
396
 
            if [ "$first" != "$second" ]; then
397
 
                echo "Passphrase mismatch" >&2
398
 
                touch "$RINGDIR"/mismatch
399
 
            else
400
 
                echo -n "$first"
401
 
            fi
402
 
        fi | gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
403
 
            --homedir "$RINGDIR" --trust-model always --armor \
404
 
            --encrypt --sign --recipient "$FINGERPRINT" --comment \
405
 
            "$FILECOMMENT" > "$SECFILE"
406
 
        if [ -e "$RINGDIR"/mismatch ]; then
407
 
            rm --force "$RINGDIR"/mismatch
408
 
            if tty --quiet; then
409
 
                > "$SECFILE"
410
 
            else
411
 
                exit 1
412
 
            fi
413
 
        fi
414
 
    done
 
281
    stty -echo
 
282
    echo -n "Enter passphrase: " >&2
 
283
    sed -e '1q' \
 
284
        | gpg --no-random-seed-file --batch --no-tty --armor \
 
285
        --no-default-keyring --no-options --enable-dsa2 \
 
286
        --homedir "$KEYDIR" --no-permission-warning \
 
287
        --secret-keyring "$SECRING" --keyring "$PUBRING" \
 
288
        --trust-model always --encrypt --recipient "$FINGERPRINT" \
 
289
        --comment "$FILECOMMENT" \
 
290
        > "$SECFILE"
 
291
    echo >&2
 
292
    stty echo
415
293
    
416
294
    cat <<-EOF
417
295
        [$KEYNAME]
418
296
        host = $KEYNAME
419
 
        EOF
420
 
    if [ -n "$KEY_ID" ]; then
421
 
        echo "key_id = $KEY_ID"
422
 
    fi
423
 
    cat <<-EOF
424
297
        fingerprint = $FINGERPRINT
425
298
        secret =
426
 
        EOF
427
 
    sed --quiet --expression='
 
299
EOF
 
300
    sed -n -e '
428
301
        /^-----BEGIN PGP MESSAGE-----$/,/^-----END PGP MESSAGE-----$/{
429
302
            /^$/,${
430
303
                # Remove 24-bit Radix-64 checksum
433
306
                /^[^-]/s/^/    /p
434
307
            }
435
308
        }' < "$SECFILE"
436
 
    if [ -n "$ssh_fingerprint" ]; then
437
 
        echo 'checker = ssh-keyscan -t '"$ssh_keytype"' %%(host)s 2>/dev/null | grep --fixed-strings --line-regexp --quiet --regexp=%%(host)s" %(ssh_fingerprint)s"'
438
 
        echo "ssh_fingerprint = ${ssh_fingerprint}"
439
 
    fi
440
309
fi
441
310
 
442
311
trap - EXIT
444
313
set +e
445
314
# Remove the password file, if any
446
315
if [ -n "$SECFILE" ]; then
447
 
    shred --remove "$SECFILE" 2>/dev/null
 
316
    shred --remove "$SECFILE"
448
317
fi
449
318
# Remove the key rings
450
 
shred --remove "$RINGDIR"/sec* 2>/dev/null
451
 
rm --recursive --force "$RINGDIR"
 
319
shred --remove "$SECRING"
 
320
rm --force "$PUBRING" "${PUBRING}~"
 
321
# Remove the trustdb, if one did not exist when we started
 
322
if [ -n "$TRUSTDB" ]; then
 
323
    rm --force "$TRUSTDB"
 
324
fi