update some scripts
[shellsnippets/shellsnippets.git] / bash-ksh / generate-pgpkey-for-at-work
1 #!/bin/sh
2 # $Id: genkey-firmengebrauch.sh 2836 2012-03-22 09:51:20Z tglase $
3 #-
4 # Copyright © 2010, 2011, 2012
5 #       Thorsten Glaser <t.glaser@tarent.de>
6 # All rights reserved.
7 #
8 # Licenced under the GNU AGPLv3.
9 #-
10 # Generate a new GnuPG (PGP) key, for company use.
11 # The keys are revokable by the company key and use LDAP user/password.
12
13 # check if we're called with mksh or bash; fix if not
14 if test -z "$shell_tried"; then
15         if test -z "$KSH_VERSION"; then
16                 if mksh -c true >/dev/null 2>&1; then
17                         shell_tried=1
18                         export shell_tried
19                         exec mksh "$0" "$@"
20                 fi
21                 if test -z "$BASH_VERSION"; then
22                         if bash -c true >/dev/null 2>&1; then
23                                 shell_tried=1
24                                 export shell_tried
25                                 exec bash "$0" "$@"
26                         fi
27                 fi
28         fi
29 fi
30 if test -z "$KSH_VERSION$BASH_VERSION"; then
31         echo >&2 "I've tried but couldn't find mksh or GNU bash."
32         echo >&2 "Please call me with one of these shells."
33         exit 1
34 fi
35 unset shell_tried
36
37 # set up some basic environment
38 export LC_ALL=C
39 unset LANG LANGUAGE
40 test -z "$BASH_VERSION" || shopt -s extglob
41 # we can now use Korn Shell extensions common to mksh and GNU bash
42
43 # initiate logging
44 cd "$(dirname "$0")"
45 log="$(basename "$0").log"
46 cat >>"$log" <<-EOF
47
48         New key generation started (Firmengebrauch)
49         $(date)
50         ===========================================
51 EOF
52 test -z "$KSH_VERSION" || echo ksh >>"$log"
53 test -z "$BASH_VERSION" || echo bash >>"$log"
54
55 # check for existence of prerequisite tools
56 for tool in gpg wget; do
57         $tool --version >/dev/null 2>&1 && continue
58         echo >&2 You must install $tool to continue.
59         exit 1
60 done
61
62 # subroutine for converting a string into an array
63 # taking into account Korn Shell vs GNU bash syntax
64 str2arr() {
65         local _a _b _s _vn=$1
66
67         eval _s=\$$_vn
68         if [[ -n $KSH_VERSION ]]; then
69                 _a="set -A $_vn -- "
70                 _b=
71         else
72                 _a="${_vn}=("
73                 _b=")"
74         fi
75         eval $_a$_s$_b
76 }
77
78 # subroutines for converting array elements into hex,
79 # printing with escapes honoured/ignored
80 # taking into account Korn Shell vs GNU bash syntax
81 if [[ -n $KSH_VERSION ]]; then
82         alias arr2hex='typeset -i16 '
83         alias eprint='print -n'
84         alias nprint='print -nr -- '
85 else
86         arr2hex() {
87                 local _vn=$1 _i _n _v
88
89                 _i=0
90                 eval _n='${#'$_vn'[*]}'
91                 while (( _i < _n )); do
92                         eval _v='${'$_vn'[_i]}'
93                         _v=$(printf '16#%x' $_v)
94                         eval $_vn'[_i++]=$_v'
95                 done
96         }
97         eprint() {
98                 printf "$@"
99         }
100         nprint() {
101                 printf '%s' "$*"
102         }
103 fi
104
105 ### BEGIN imported code {{{
106 # Copyright (c) 2008
107 #       Thorsten Glaser <tg@mirbsd.org>
108 #
109 # Provided that these terms and disclaimer and all copyright notices
110 # are retained or reproduced in an accompanying document, permission
111 # is granted to deal in this work without restriction, including un-
112 # limited rights to use, publicly perform, distribute, sell, modify,
113 # merge, give away, or sublicence.
114 #
115 # This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
116 # the utmost extent permitted by applicable law, neither express nor
117 # implied; without malicious intent or gross negligence. In no event
118 # may a licensor, author or contributor be held liable for indirect,
119 # direct, other damage, loss, or other issues arising in any way out
120 # of dealing in the work, even if advised of the possibility of such
121 # damage or existence of a defect, except proven that it results out
122 # of said person's immediate fault when using the work as intended.
123
124 # read a password without echoing
125 askpass() {
126         set -o noglob
127         stty -echo
128         echo -n "$1 "
129         read resp
130         stty echo
131         set +o noglob
132         echo
133 }
134
135 # convert a string from UTF-8 or ISO-8859-1 to UTF-8
136 str2utf8() {
137         local _s="$*" _z _c _i _hv _wc _n
138
139         _c=$(nprint "$_s" | hexdump -ve '1/1 "16#%x "')
140         _c="$_c 0"
141         str2arr _c
142         _s=
143         _z=0
144         _i=0
145         while (( _c[_i] )); do
146                 (( _hv = _c[_i] ))
147                 if (( (_hv < 16#C2) || (_hv >= 16#F0) )); then
148                         _n=1
149                 elif (( _hv < 16#E0 )); then
150                         _n=2
151                 else
152                         _n=3
153                 fi
154                 if (( _n > 1 )); then
155                         (( (_c[_i + 1] & 16#C0) == 16#80 )) || _n=1
156                         (( _hv == 16#E0 )) && \
157                             (( _c[_i + 1] < 16#A0 )) && _n=1
158                 fi
159                 if (( _n > 2 )); then
160                         (( (_c[_i + 2] & 16#C0) == 16#80 )) || _n=1
161                         (( _hv == 16#EF && _c[_i + 1] == 16#EF && \
162                             _c[_i + 2] > 16#BD )) && _n=1
163                 fi
164                 case $_n in
165                 (1)
166                         if (( (_wc = _c[_i]) < 16#80 )); then
167                                 (( _s[_z++] = _wc ))
168                         else
169                                 (( _s[_z++] = 16#C0 | (_wc >> 6) ))
170                                 (( _s[_z++] = 16#80 | (_wc & 16#3F) ))
171                         fi
172                         ;;
173                 (2)
174                         (( _s[_z++] = _c[_i] ))
175                         (( _s[_z++] = _c[_i + 1] ))
176                         ;;
177                 (3)
178                         (( _s[_z++] = _c[_i] ))
179                         (( _s[_z++] = _c[_i + 1] ))
180                         (( _s[_z++] = _c[_i + 2] ))
181                         ;;
182                 esac
183                 (( _i += _n ))
184         done
185         arr2hex _s
186         eprint "$(echo ${_s[*]} | sed -e 's/16#/\\x/g' -e 's/ //g')"
187 }
188
189 ### END imported code }}}
190
191 # create a temporary directory in /dev/shm (Linux tmpfs) or /tmp (otherwise)
192 if [[ ! -d /dev/shm/. ]] || ! T=$(mktemp -d /dev/shm/genkey.XXXXXXXXXX); then
193         if ! T=$(mktemp -d /tmp/genkey.XXXXXXXXXX); then
194                 echo >&2 Cannot create temporary directory.
195                 exit 1
196         fi
197 fi
198
199 cleanup() {
200         trap - 0 1 2 3 13 15
201         # files to overwrite before removing
202         for wipefiles in resp wgetrc; do
203                 for x in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
204                         echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
205                 done >"$T/$wipefiles"
206         done
207         sync
208         rm -rf "$T"
209         exit $1
210 }
211
212 # make sure the temporary files are removed if we are interrupted
213 trap "cleanup 1" 1 2 3 13 15
214 trap "cleanup 0" 0
215
216
217 # import company key (delete first, just in case)
218 ckid=3166EA4AF24EFF313803A739EEABC048D0620C0F
219 gpg --batch --delete-key $ckid
220 gpg --import --batch <<'EOF'
221 -----BEGIN PGP PUBLIC KEY BLOCK-----
222 Version: GnuPG v1.4.9 (MirBSD)
223
224 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
258 4wBQF+0/W2exE5FX3pCwrYUmYe/ItsnAZKY5RA==
259 =tDFz
260 -----END PGP PUBLIC KEY BLOCK-----
261 EOF
262
263
264 # show introduction
265 echo "
266 tarent solutions GmbH - PGP Key Generation
267 ==========================================
268
269 [de] Ein PGP-Schlüsselpaar wird jetzt erstellt und der öffentliche Teil
270      an den tarent-Server übertragen, sodaß die Admins diesen signieren
271      und veröffentlichen können. Außerdem wird mit diesem Schlüssel der
272      Firmenschlüssel unterschrieben; diese Signatur wird ebenfalls ver-
273      öffentlicht. Dein Name und eMail-Adresse wird aus dem LDAP bezogen
274      und das LDAP-Paßwort auch für den privaten Schlüssel verwendet.
275
276 [en] We will now generate a PGP keypair; the public key will be submit-
277      ted to the tarent server for being signed and published by the ad-
278      mins. The freshly generated key will also be used to sign and pub-
279      lish the company key. Your name and eMail address information will
280      be taken from the LDAP; the LDAP password will be used as password
281      for the secret key.
282 "
283
284 # request and record user/pass
285 echo -n "LDAP login Username: "
286 read un
287 [[ -n $un ]] || cleanup 0
288 askpass "LDAP login Password:"
289 [[ -n $resp ]] || cleanup 0
290
291 echo "login: $un" >>"$log"
292
293 # create wgetrc(5) to use for HTTP Basic Authentication
294 export WGETRC="$T/wgetrc"
295 cat >"$WGETRC" <<EOF
296 password = $resp
297 user = $un
298 EOF
299
300 # create CA “bundle”
301 cat >"$T/ca.cer" <<'EOF'
302 -----BEGIN CERTIFICATE-----
303 MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
304 IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
305 BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
306 aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
307 9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy
308 NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
309 azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
310 YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
311 Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
312 cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY
313 dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9
314 WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS
315 v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v
316 UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu
317 IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
318 W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
319 -----END CERTIFICATE-----
320 EOF
321
322 # get user information from LDAP
323 x=$(wget -O "$T/ui" --ca-certificate="$T/ca.cer" -S https://tarentpgp.tarent.de/ui.cgi 2>&1 | \
324     if md5sum --version >/dev/null 2>&1; then
325         md5sum | sed 's/ .*$//'
326 else
327         md5
328 fi | sed 's/../16#& /g')
329 (echo "got user info {"; sed 's/^/      /' <"$T/ui"; echo "}") >>"$log"
330
331 # add entropy from CGIs to that pool (magic code ;) {{{
332 if [[ ! -s ~/.gnupg/random_seed ]]; then
333         # create and fill if it didn't exist
334         :>~/.gnupg/random_seed
335         chmod 0600 ~/.gnupg/random_seed
336         dd if=/dev/urandom of=~/.gnupg/random_seed bs=600 count=1
337 fi
338 entropy=$(wget -O - -T 10 --ca-certificate="$T/ca.cer" \
339     https://spamfilter3.tarent.de/lb.cgi?genkey.sh,1=$(hostname -f),seed=$RANDOM$RANDOM$RANDOM$RANDOM$RANDOM 2>/dev/null | \
340     hexdump -ve '1/1 "16#%x "')$x
341 poolfile=$(hexdump -ve '1/1 "16#%x "' <~/.gnupg/random_seed)
342 str2arr entropy
343 str2arr poolfile
344 (( n = ${#poolfile[*]} < ${#entropy[*]} ? ${#entropy[*]} : ${#poolfile[*]} ))
345 i=0
346 # XOR poolfile with new entropy (from CGIs)
347 while (( i < n )); do
348         (( poolfile[i % ${#poolfile[*]}] ^= entropy[i % ${#entropy[*]}] ))
349         let i++
350 done
351 # write back into the pool file
352 arr2hex poolfile
353 eprint "$(echo ${poolfile[*]} | sed -e 's/16#/\\x/g' -e 's/ //g')" | \
354     dd of=~/.gnupg/random_seed conv=notrunc 2>/dev/null
355 # }}} end of magic code block ;)
356
357 # check the user information
358 status=bad
359 i_name=
360 i_mail=
361 i_comm=
362 while read key value; do
363         case x$key in
364         (xstatus)
365                 [[ $value = ok ]] || break
366                 [[ $status = bad ]] && status=good
367                 ;;
368         (xname|xmail|xcomm)
369                 eval i_$key=\$value
370                 ;;
371         (x)
372                 ;;
373         (*)
374                 echo >&2 "Invalid server response '$key $value'"
375                 status=invalid
376                 ;;
377         esac
378 done <"$T/ui"
379 if [[ $status != good || -z $i_name || -z $i_mail ]]; then
380         echo >&2 "Cannot process further (status: $status)"
381         [[ $status = bad ]] && echo >&2 Maybe wrong password.
382         cleanup 1
383 fi
384
385 # create response file for gpg
386 # NOTE: Key-Length can go up to 8192 (not more!) but please no lower
387 #       than 2048 (although more than 4096 may be incompatible *AND*
388 #       TERRIBLY SLOW)
389 cat >"$T/resp" <<-EOF
390         %echo Generating the key for $i_name ($i_mail) $i_comm
391         Key-Type: RSA
392         Key-Length: 3072
393         Key-Usage: auth,encrypt,sign
394         Passphrase: $(str2utf8 "$resp")
395         Name-Real: $(str2utf8 "$i_name")
396         ${i_comm:+Name-Comment: $(str2utf8 "$i_comm")}
397         Name-Email: $(str2utf8 "$i_mail")
398         Expire-Date: 3y
399         Preferences: H8 H3 S8 S4 Z2 Z0 H9 H10 S9 S7
400         Revoker: 1:$ckid
401         Keyserver: hkp://tarentpgp.tarent.de
402         %commit
403         %echo done
404 EOF
405
406 # really generate the key
407 echo
408 (gpg --no-use-agent --batch --gen-key "$T/resp"; echo $? >"$T/rc") 2>&1 | \
409     tee "$T/gen.out"
410 echo
411 (echo "create key {"; sed 's/^/ /' <"$T/gen.out"; echo "}") >>"$log"
412 # check for error exit
413 if (( $(<"$T/rc") > 0 )); then
414         echo >&2 Key generation failed.
415         cleanup 1
416 fi
417 # scan the gpg log for keyid of keypair just created
418 pkid=$(sed -n \
419     's/^gpg: key \([0-9A-F]*\) marked as ultimately trusted.*$/\1/p' \
420     "$T/gen.out")
421 if [[ $pkid != +([0-9A-F]) ]] || ! gpg -K $pkid; then
422         echo >&2 '┌─────────────────────────────────────────────────────────┐'
423         echo >&2 '│ Finding the key failed. YOU CAN USE THE KEY, BUT YOU    │'
424         echo >&2 '│ *MUST* CONTACT THE ADMINS with this error message.      │'
425         echo >&2 '│ Kann den neuen Schlüssel nicht finden. DU KANNST DIESES │'
426         echo >&2 '│ SCHLÜSSELPAAR BENUTZEN, ABER DU *MUẞT* DIE ADMINS mit   │'
427         echo >&2 '│ dieser Fehlernachricht KONTAKTIEREN.                    │'
428         echo >&2 '└─────────────────────────────────────────────────────────┘'
429         echo
430         echo >&2 Cannot find the key just generated.
431         cleanup 1
432 fi
433
434 # apply preference settings to our newly generated key
435 gpg --no-use-agent -q -u $pkid --command-fd 4 --edit-key $pkid \
436     >>"$T/edit.log" 2>&1 4<<-EOF
437         notation preferred-email-encoding@pgp.com=partitioned,pgpmime
438         $(str2utf8 "$resp")
439         trust
440         5
441         y
442         uid 1
443         primary
444         $(str2utf8 "$resp")
445         adduid
446         $(str2utf8 "$i_name")
447         $(str2utf8 "$un")@info.tarent.de
448         Jabber/XMPP
449         $(str2utf8 "$resp")
450         uid 1
451         uid 2
452         setpref H8 H3 S8 S4 Z2 Z0 Z1 H9 H10 S9 S7
453         y
454         $(str2utf8 "$resp")
455         keyserver hkp://tarentpgp.tarent.de
456         $(str2utf8 "$resp")
457         save
458 EOF
459 echo "=> $?" >>"$T/edit.log"
460
461 # sign the company key with that key
462 # XXX if the key has >1 UID, there must be an extra line
463 #       y
464 # after the line saying "tsign"!
465 gpg --no-ask-cert-level --no-expert --no-use-agent -q -u $pkid --command-fd 4 --edit-key $ckid \
466     >>"$T/edit.log" 2>&1 4<<-EOF
467         tsign
468         2
469         2
470
471         y
472         $(str2utf8 "$resp")
473         trust
474         4
475         save
476 EOF
477 echo "=> $?" >>"$T/edit.log"
478 sed 's/^/│/' "$T/edit.log" >>"$log"
479
480 # export our own public key and the signed company key into a keyring
481 rc=0
482 gpg --export-options no-export-attributes,export-clean \
483     --export $ckid >"$T/exp.c" 2>>"$log" || rc=$?
484 gpg --export-options no-export-attributes,export-clean,export-minimal \
485     --export $pkid >"$T/exp.p" 2>>"$log" || rc=$?
486 rm -f "$T/exp.kr"
487 GNUPGHOME="$T/.gnupg" gpg --no-default-keyring --primary-keyring "$T/exp.kr" \
488     --import "$T/exp.c" 2>>"$log" || rc=$?
489 GNUPGHOME="$T/.gnupg" gpg --no-default-keyring --primary-keyring "$T/exp.kr" \
490     --import "$T/exp.p" 2>>"$log" || rc=$?
491 echo >>"$log"
492 if (( rc )); then
493         (echo "export error $rc"; gpg -k $pkid; echo "=> $?") >>"$log"
494         echo >&2 '┌────────────────────────────────────────────────────────┐'
495         echo >&2 '│ Exporting the key failed. YOU CAN USE THE KEY, BUT YOU │'
496         echo >&2 '│ *MUST* CONTACT THE ADMINS with this error message.     │'
497         echo >&2 '│ Export des Schlüssels fehlgeschlagen. DU KANNST DIESES │'
498         echo >&2 '│ SCHLÜSSELPAAR BENUTZEN, ABER DU *MUẞT* DIE ADMINS mit  │'
499         echo >&2 '│ dieser Fehlernachricht KONTAKTIEREN.                   │'
500         echo >&2 '└────────────────────────────────────────────────────────┘'
501         echo
502         gpg -k $pkid || echo gpg ERROR -k: $?
503         cleanup 0
504 fi
505 echo "export ok" >>"$log"
506 GNUPGHOME="$T/.gnupg" gpg --no-default-keyring --primary-keyring "$T/exp.kr" \
507     --list-sigs >>"$log" 2>&1
508
509 # upload the exported keyring
510 wget -O "$T/upload" \
511     --header="Content-type: application/octet-stream" \
512     --post-file="$T/exp.kr" \
513     --ca-certificate="$T/ca.cer" \
514     https://tarentpgp.tarent.de/fu.cgi >"$T/upload.log" 2>&1
515 (echo "upload keyring {"; sed 's/^/[    /' <"$T/upload.log"; \
516     sed 's/^/]  /' <"$T/upload"; echo "}") >>"$log"
517 echo
518 if [[ $(head -1 "$T/upload") != "upload ok" ]]; then
519         echo >&2 '┌────────────────────────────────────────────────────────┐'
520         echo >&2 '│ Uploading the key failed. YOU CAN USE THE KEY, BUT YOU │'
521         echo >&2 '│ *MUST* CONTACT THE ADMINS with this error message.     │'
522         echo >&2 '│ Upload des Schlüssels fehlgeschlagen. DU KANNST DIESES │'
523         echo >&2 '│ SCHLÜSSELPAAR BENUTZEN, ABER DU *MUẞT* DIE ADMINS mit  │'
524         echo >&2 '│ dieser Fehlernachricht KONTAKTIEREN.                   │'
525         echo >&2 '└────────────────────────────────────────────────────────┘'
526 else
527         cat >&2 <<'EOF'
528 ┌─────────────────────────────────────────┐
529 │ Key generation finished with no errors. │
530 │ Schlüsselerzeugung fehlerfrei erledigt. │
531 └─────────────────────────────────────────┘
532
533 ╔═════════════════════════════════════════════════════════════════════╗
534 ║ You are responsible for backing up yout PGP secret key BY YOURSELF! ║
535 ║ Du mußt SELBER für Sicherungskopiën des privaten Schlüssels sorgen! ║
536 ╚═════════════════════════════════════════════════════════════════════╝
537 EOF
538 fi
539 (echo "finished:"; gpg -k $pkid | sed 's/^/|    /'; echo) >>"$log"
540 echo >&2
541 gpg -k $pkid || echo gpg ERROR -k: $?
542 cleanup 0