/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: 2024-11-17 18:43:11 UTC
  • Revision ID: teddy@recompile.se-20241117184311-ox25kvngy62h209g
Debian package: Avoid suggesting a C compiler unnecessarily

The list of suggested packages, meant to enable the "mandos" program
to find the correct value of SO_BINDTODEVICE by using a C compiler,
are not necessary when Python 3.3 or later is used, since it has the
SO_BINDTODEVICE constant defined in the "socket" module.  Also, Python
2.6 or older has the same constant in the old "IN" module.  Therefore,
we should suggest these Python versions as alternatives to a C
compiler, so that a C compiler is not installed unnecessarily.

debian/control (Package: mandos/Suggests): Add "python3 (>= 3.3)" and
"python (<= 2.6)" as alternatives to "libc6-dev | libc-dev" and
"c-compiler".

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#!/bin/sh -e
2
2
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
 
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
9
12
# the Free Software Foundation, either version 3 of the License, or
10
13
# (at your option) any later version.
11
14
#
12
 
#     This program is distributed in the hope that it will be useful,
13
 
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
#     Mandos is distributed in the hope that it will be useful, but
 
16
#     WITHOUT ANY WARRANTY; without even the implied warranty of
14
17
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
18
#     GNU General Public License for more details.
16
19
17
20
# You should have received a copy of the GNU General Public License
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`"
 
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.17"
 
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`"
31
34
KEYEMAIL=""
32
 
KEYCOMMENT="Mandos client key"
 
35
KEYCOMMENT=""
33
36
KEYEXPIRE=0
 
37
TLS_KEYTYPE=ed25519
34
38
FORCE=no
 
39
SSH=yes
35
40
KEYCOMMENT_ORIG="$KEYCOMMENT"
36
41
mode=keygen
37
42
 
 
43
if [ ! -d "$KEYDIR" ]; then
 
44
    KEYDIR="/etc/mandos/keys"
 
45
fi
 
46
 
38
47
# Parse options
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 \
 
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 \
41
50
    --name "$0" -- "$@"`
42
51
 
43
52
help(){
44
 
basename="`basename $0`"
 
53
basename="`basename "$0"`"
45
54
cat <<EOF
46
55
Usage: $basename [ -v | --version ]
47
56
       $basename [ -h | --help ]
49
58
       $basename [ OPTIONS ]
50
59
   Encrypted password creation:
51
60
       $basename { -p | --password } [ --name NAME ] [ --dir DIR]
 
61
       $basename { -F | --passfile } FILE [ --name NAME ] [ --dir DIR]
52
62
 
53
63
Key creation options:
54
64
  -v, --version         Show program's version number and exit
55
65
  -h, --help            Show this help message and exit
56
66
  -d DIR, --dir DIR     Target directory for key files
57
 
  -t TYPE, --type TYPE  Key type.  Default is DSA.
 
67
  -t TYPE, --type TYPE  OpenPGP key type.  Default is RSA.
58
68
  -l BITS, --length BITS
59
 
                        Key length in bits.  Default is 2048.
 
69
                        OpenPGP key length in bits.  Default is 4096.
60
70
  -s TYPE, --subtype TYPE
61
 
                        Subkey type.  Default is ELG-E.
 
71
                        OpenPGP subkey type.  Default is RSA.
62
72
  -L BITS, --sublength BITS
63
 
                        Subkey length in bits.  Default is 2048.
 
73
                        OpenPGP subkey length in bits.  Default 4096.
64
74
  -n NAME, --name NAME  Name of key.  Default is the FQDN.
65
75
  -e ADDRESS, --email ADDRESS
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".
 
76
                        Email address of OpenPGP key.  Default empty.
 
77
  -c TEXT, --comment TEXT
 
78
                        Comment field for OpenPGP key.  Default empty.
70
79
  -x TIME, --expire TIME
71
 
                        Key expire time.  Default is no expiration.
 
80
                        OpenPGP key expire time.  Default is none.
72
81
                        See gpg(1) for syntax.
73
 
  -f, --force           Force overwriting old keys.
 
82
  -T TYPE, --tls-keytype TYPE
 
83
                        TLS key type.  Default is ed25519.
 
84
  -f, --force           Force overwriting old key files.
74
85
 
75
86
Password creation options:
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.
 
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.
79
95
EOF
80
96
}
81
97
 
83
99
while :; do
84
100
    case "$1" in
85
101
        -p|--password) mode=password; shift;;
 
102
        -F|--passfile) mode=password; PASSFILE="$2"; shift 2;;
86
103
        -d|--dir) KEYDIR="$2"; shift 2;;
87
104
        -t|--type) KEYTYPE="$2"; shift 2;;
88
105
        -s|--subtype) SUBKEYTYPE="$2"; shift 2;;
92
109
        -e|--email) KEYEMAIL="$2"; shift 2;;
93
110
        -c|--comment) KEYCOMMENT="$2"; shift 2;;
94
111
        -x|--expire) KEYEXPIRE="$2"; shift 2;;
 
112
        -T|--tls-keytype) TLS_KEYTYPE="$2"; shift 2;;
95
113
        -f|--force) FORCE=yes; shift;;
 
114
        -S|--no-ssh) SSH=no; shift;;
96
115
        -v|--version) echo "$0 $VERSION"; exit;;
97
116
        -h|--help) help; exit;;
98
117
        --) shift; break;;
100
119
    esac
101
120
done
102
121
if [ "$#" -gt 0 ]; then
103
 
    echo "Unknown arguments: '$@'" >&2
 
122
    echo "Unknown arguments: '$*'" >&2
104
123
    exit 1
105
124
fi
106
125
 
107
126
SECKEYFILE="$KEYDIR/seckey.txt"
108
127
PUBKEYFILE="$KEYDIR/pubkey.txt"
 
128
TLS_PRIVKEYFILE="$KEYDIR/tls-privkey.pem"
 
129
TLS_PUBKEYFILE="$KEYDIR/tls-pubkey.pem"
109
130
 
110
131
# Check for some invalid values
111
 
if [ -d "$KEYDIR" ]; then :; else
 
132
if [ ! -d "$KEYDIR" ]; then
112
133
    echo "$KEYDIR not a directory" >&2
113
134
    exit 1
114
135
fi
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
 
136
if [ ! -r "$KEYDIR" ]; then
 
137
    echo "Directory $KEYDIR not readable" >&2
122
138
    exit 1
123
139
fi
124
140
 
125
141
if [ "$mode" = keygen ]; then
 
142
    if [ ! -w "$KEYDIR" ]; then
 
143
        echo "Directory $KEYDIR not writeable" >&2
 
144
        exit 1
 
145
    fi
126
146
    if [ -z "$KEYTYPE" ]; then
127
147
        echo "Empty key type" >&2
128
148
        exit 1
129
149
    fi
130
 
    
 
150
 
131
151
    if [ -z "$KEYNAME" ]; then
132
152
        echo "Empty key name" >&2
133
153
        exit 1
134
154
    fi
135
 
    
 
155
 
136
156
    if [ -z "$KEYLENGTH" ] || [ "$KEYLENGTH" -lt 512 ]; then
137
157
        echo "Invalid key length" >&2
138
158
        exit 1
142
162
        echo "Empty key expiration" >&2
143
163
        exit 1
144
164
    fi
145
 
    
 
165
 
146
166
    # Make FORCE be 0 or 1
147
167
    case "$FORCE" in
148
168
        [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]) FORCE=1;;
149
169
        [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|*) FORCE=0;;
150
170
    esac
151
 
    
152
 
    if { [ -e "$SECKEYFILE" ] || [ -e "$PUBKEYFILE" ]; } \
 
171
 
 
172
    if { [ -e "$SECKEYFILE" ] || [ -e "$PUBKEYFILE" ] \
 
173
             || [ -e "$TLS_PRIVKEYFILE" ] \
 
174
             || [ -e "$TLS_PUBKEYFILE" ]; } \
153
175
        && [ "$FORCE" -eq 0 ]; then
154
176
        echo "Refusing to overwrite old key files; use --force" >&2
155
177
        exit 1
156
178
    fi
157
 
    
 
179
 
158
180
    # Set lines for GnuPG batch file
159
181
    if [ -n "$KEYCOMMENT" ]; then
160
182
        KEYCOMMENTLINE="Name-Comment: $KEYCOMMENT"
164
186
    fi
165
187
 
166
188
    # Create temporary gpg batch file
167
 
    BATCHFILE="`mktemp -t mandos-gpg-batch.XXXXXXXXXX`"
 
189
    BATCHFILE="`mktemp -t mandos-keygen-batch.XXXXXXXXXX`"
 
190
    TLS_PRIVKEYTMP="`mktemp -t mandos-keygen-privkey.XXXXXXXXXX`"
168
191
fi
169
192
 
170
193
if [ "$mode" = password ]; then
171
194
    # Create temporary encrypted password file
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
 
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`"
186
200
 
187
201
# Remove temporary files on exit
188
202
trap "
189
203
set +e; \
190
 
rm --force $PUBRING ${PUBRING}~ $BATCHFILE $TRUSTDB; \
191
 
shred --remove $SECRING $SECFILE; \
192
 
stty echo; \
 
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; \
193
210
" EXIT
194
211
 
195
 
umask 027
 
212
set -e
 
213
 
 
214
umask 077
196
215
 
197
216
if [ "$mode" = keygen ]; then
198
217
    # Create batch file for GnuPG
199
218
    cat >"$BATCHFILE" <<-EOF
200
219
        Key-Type: $KEYTYPE
201
220
        Key-Length: $KEYLENGTH
202
 
        #Key-Usage: encrypt,sign,auth
 
221
        Key-Usage: sign,auth
203
222
        Subkey-Type: $SUBKEYTYPE
204
223
        Subkey-Length: $SUBKEYLENGTH
205
 
        #Subkey-Usage: encrypt,sign,auth
 
224
        Subkey-Usage: encrypt
206
225
        Name-Real: $KEYNAME
207
226
        $KEYCOMMENTLINE
208
227
        $KEYEMAILLINE
209
228
        Expire-Date: $KEYEXPIRE
210
229
        #Preferences: <string>
211
230
        #Handle: <no-spaces>
212
 
        %pubring $PUBRING
213
 
        %secring $SECRING
 
231
        #%pubring pubring.gpg
 
232
        #%secring secring.gpg
 
233
        %no-protection
214
234
        %commit
215
235
        EOF
216
 
    
 
236
 
 
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
217
285
    # Generate a new key in the key rings
218
 
    gpg --no-random-seed-file --quiet --batch --no-tty \
219
 
        --no-default-keyring --no-options --enable-dsa2 \
220
 
        --secret-keyring "$SECRING" --keyring "$PUBRING" \
 
286
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
 
287
        --homedir "$RINGDIR" --trust-model always \
221
288
        --gen-key "$BATCHFILE"
222
289
    rm --force "$BATCHFILE"
223
290
 
 
291
    if tty --quiet; then
 
292
        echo -n "Finished: "
 
293
        date
 
294
    fi
 
295
 
224
296
    # Backup any old key files
225
297
    if cp --backup=numbered --force "$SECKEYFILE" "$SECKEYFILE" \
226
298
        2>/dev/null; then
227
 
        shred --remove "$SECKEYFILE"
 
299
        shred --remove "$SECKEYFILE" 2>/dev/null || :
228
300
    fi
229
301
    if cp --backup=numbered --force "$PUBKEYFILE" "$PUBKEYFILE" \
230
302
        2>/dev/null; then
231
303
        rm --force "$PUBKEYFILE"
232
304
    fi
233
 
    
 
305
 
234
306
    FILECOMMENT="Mandos client key for $KEYNAME"
235
307
    if [ "$KEYCOMMENT" != "$KEYCOMMENT_ORIG" ]; then
236
308
        FILECOMMENT="$FILECOMMENT ($KEYCOMMENT)"
237
309
    fi
238
 
    
 
310
 
239
311
    if [ -n "$KEYEMAIL" ]; then
240
312
        FILECOMMENT="$FILECOMMENT <$KEYEMAIL>"
241
313
    fi
242
 
    
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
 
314
 
 
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
254
323
fi
255
324
 
256
325
if [ "$mode" = password ]; then
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"
 
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
        # The -q option is new in OpenSSH 9.8
 
335
        for ssh_keyscan_quiet in "-q " ""; do
 
336
            for ssh_keytype in ecdsa-sha2-nistp256 ed25519 rsa; do
 
337
                set +e
 
338
                ssh_fingerprint="`ssh-keyscan ${ssh_keyscan_quiet}-t $ssh_keytype localhost 2>/dev/null`"
 
339
                err=$?
 
340
                set -e
 
341
                if [ $err -ne 0 ]; then
 
342
                    ssh_fingerprint=""
 
343
                    continue
 
344
                fi
 
345
                if [ -n "$ssh_fingerprint" ]; then
 
346
                    ssh_fingerprint="${ssh_fingerprint#localhost }"
 
347
                    break 2
 
348
                fi
 
349
            done
 
350
        done
 
351
    fi
 
352
 
 
353
    # Import key into temporary key rings
 
354
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
 
355
        --homedir "$RINGDIR" --trust-model always --armor \
 
356
        --import "$SECKEYFILE"
 
357
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
 
358
        --homedir "$RINGDIR" --trust-model always --armor \
 
359
        --import "$PUBKEYFILE"
268
360
 
269
361
    # Get fingerprint of key
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}'`"
276
 
    
 
362
    FINGERPRINT="`gpg --quiet --batch --no-tty --no-options \
 
363
        --enable-dsa2 --homedir "$RINGDIR" --trust-model always \
 
364
        --fingerprint --with-colons \
 
365
        | sed --quiet \
 
366
        --expression='/^fpr:/{s/^fpr:.*:\\([0-9A-Z]*\\):\$/\\1/p;q}'`"
 
367
 
277
368
    test -n "$FINGERPRINT"
278
 
    
 
369
 
 
370
    if [ -r "$TLS_PUBKEYFILE" ]; then
 
371
       KEY_ID="$(certtool --key-id --hash=sha256 \
 
372
                       --infile="$TLS_PUBKEYFILE" 2>/dev/null || :)"
 
373
 
 
374
       if [ -z "$KEY_ID" ]; then
 
375
           KEY_ID=$(openssl pkey -pubin -in "$TLS_PUBKEYFILE" \
 
376
                            -outform der \
 
377
                        | openssl sha256 \
 
378
                        | sed --expression='s/^.*[^[:xdigit:]]//')
 
379
       fi
 
380
       test -n "$KEY_ID"
 
381
    fi
 
382
 
279
383
    FILECOMMENT="Encrypted password for a Mandos client"
280
 
    
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
293
 
    
 
384
 
 
385
    while [ ! -s "$SECFILE" ]; do
 
386
        if [ -n "$PASSFILE" ]; then
 
387
            cat -- "$PASSFILE"
 
388
        else
 
389
            tty --quiet && stty -echo
 
390
            echo -n "Enter passphrase: " >/dev/tty
 
391
            read -r first
 
392
            tty --quiet && echo >&2
 
393
            echo -n "Repeat passphrase: " >/dev/tty
 
394
            read -r second
 
395
            if tty --quiet; then
 
396
                echo >&2
 
397
                stty echo
 
398
            fi
 
399
            if [ "$first" != "$second" ]; then
 
400
                echo "Passphrase mismatch" >&2
 
401
                touch "$RINGDIR"/mismatch
 
402
            else
 
403
                printf "%s" "$first"
 
404
            fi
 
405
        fi | gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
 
406
            --homedir "$RINGDIR" --trust-model always --armor \
 
407
            --encrypt --sign --recipient "$FINGERPRINT" --comment \
 
408
            "$FILECOMMENT" > "$SECFILE"
 
409
        if [ -e "$RINGDIR"/mismatch ]; then
 
410
            rm --force "$RINGDIR"/mismatch
 
411
            if tty --quiet; then
 
412
                > "$SECFILE"
 
413
            else
 
414
                exit 1
 
415
            fi
 
416
        fi
 
417
    done
 
418
 
294
419
    cat <<-EOF
295
420
        [$KEYNAME]
296
421
        host = $KEYNAME
 
422
        EOF
 
423
    if [ -n "$KEY_ID" ]; then
 
424
        echo "key_id = $KEY_ID"
 
425
    fi
 
426
    cat <<-EOF
297
427
        fingerprint = $FINGERPRINT
298
428
        secret =
299
 
EOF
300
 
    sed -n -e '
 
429
        EOF
 
430
    sed --quiet --expression='
301
431
        /^-----BEGIN PGP MESSAGE-----$/,/^-----END PGP MESSAGE-----$/{
302
432
            /^$/,${
303
433
                # Remove 24-bit Radix-64 checksum
306
436
                /^[^-]/s/^/    /p
307
437
            }
308
438
        }' < "$SECFILE"
 
439
    if [ -n "$ssh_fingerprint" ]; then
 
440
        echo 'checker = ssh-keyscan '"$ssh_keyscan_quiet"'-t '"$ssh_keytype"' %%(host)s 2>/dev/null | grep --fixed-strings --line-regexp --quiet --regexp=%%(host)s" %(ssh_fingerprint)s"'
 
441
        echo "ssh_fingerprint = ${ssh_fingerprint}"
 
442
    fi
309
443
fi
310
444
 
311
445
trap - EXIT
313
447
set +e
314
448
# Remove the password file, if any
315
449
if [ -n "$SECFILE" ]; then
316
 
    shred --remove "$SECFILE"
 
450
    shred --remove "$SECFILE" 2>/dev/null
317
451
fi
318
452
# Remove the key rings
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
 
453
shred --remove "$RINGDIR"/sec* 2>/dev/null
 
454
rm --recursive --force "$RINGDIR"