3 ### Generate a new recovery key and split it among keepers
5 ### (c) 2011 Mark Wooding
8 ###----- Licensing notice ---------------------------------------------------
10 ### This file is part of the distorted.org.uk key management suite.
12 ### distorted-keys is free software; you can redistribute it and/or modify
13 ### it under the terms of the GNU General Public License as published by
14 ### the Free Software Foundation; either version 2 of the License, or
15 ### (at your option) any later version.
17 ### distorted-keys is distributed in the hope that it will be useful,
18 ### but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ### GNU General Public License for more details.
22 ### You should have received a copy of the GNU General Public License
23 ### along with distorted-keys; if not, write to the Free Software Foundation,
24 ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 case "${KEYSLIB+t}" in t
) ;; *) echo >&2 "$0: KEYSLIB unset"; exit 1 ;; esac
28 .
"$KEYSLIB"/keyfunc.sh
31 [-p PROFILE] RECOV [KEEPER:K ...] [-- OPTION=VALUE ...]
32 Generate a new recovery secret, and split it among the available keepers.
34 The new secret will be called RECOV. For each KEEPER set, the private key
35 wil be split into shares, and encrypted with the KEEPER's public keys; any K
36 of these shares can be used to reveal the original key.
38 If there is already a recovery key called RECOV then it will be rolled over.
39 The previous key must already be revealed. If KEEPERs are listed, these
40 replace the existing keeper sets; otherwise the same keepers as before are
43 If there is not a recovery key called RECOV then at least one keeper set must
47 ## Parse the command line.
48 profile
=${recov_profile-recovery}
49 while getopts "p:" opt
; do
55 shift $
(( $OPTIND - 1 ))
56 case $# in 0) usage_err
;; esac
58 checkword
"recovery key label" "$recov"
59 checkword
"profile label" "$profile"
65 *) echo >&2 "$quis: bad keeper spec \`$k'"; exit 1 ;;
67 keeper
=${k%:*} t
=${k#*:} nkeep
=$
(( $nkeep + 1 ))
68 checkword
"keeper set label" "$keeper"
69 checknumber
"keeper quorum" "$t"
72 ## Establish the keeper parameters.
73 rdir
=$KEYS/recov
/$recov
74 if [ ! -d
$rdir ]; then mkdir
-m755
-p
$rdir; fi
81 case "$k" in --) break ;; esac
82 keeper
=${k%:*} t
=${k#*:}
84 done >$rdir/keepers.new
85 kparam
=$rdir/keepers.new
88 if [ ! -f
$kparam ]; then echo >&2 "$quis: no keepers specified"; exit 1; fi
90 ## Make the new key and issue the shares.
103 c_gensyskey
$profile $rdir/new
/store secret recov
="$recov" "$@"
104 while read keeper k
; do
105 read n hunoz
<$KEYS/keeper
/$keeper/meta
106 $bindir/shamir issue
$k/$n secret |
{
108 echo "$param" >$rdir/new
/$keeper.param
111 c_sysencrypt
$KEYS/keeper
/$keeper/$i >$rdir/new
/$keeper.
$i.share
<<EOF
120 ## If there's an existing instance of this key, transfer the recovery blobs.
121 if [ ! -d
$rdir/current
]; then
124 seq=$
(readlink
$rdir/current
)
126 reveal
=$SAFE/keys.reveal
/$recov.current
/secret
127 if [ ! -f
$reveal ]; then
128 echo >&2 "$quis: current $recov key not revealed"
132 find $rdir/current
/ -type f
-name
'*.recov' -print |
while read name
; do
133 name
=${name#$rdir/current/}
134 case "$name" in */*) mkdir
-p
-m755
$rdir/new
/${name%/*} ;; esac
135 c_sysdecrypt
$rdir/current
/store
$reveal <$rdir/current
/$name >tmp
136 c_sysencrypt
$rdir/new
/store
<tmp
>$rdir/new
/$name
139 rm -r
$SAFE/keys.reveal
/$recov.current
142 ## Tidy up and commit. Repointing the symlink is grim because, according to
143 ## POSIX rules, `mv foo bar' should rename `foo' to `bar/foo' is `bar' is a
144 ## symlink to a directory -- and there's no way of turning this behaviour
145 ## off. The subterfuge here is due to Colin Watson.
147 while [ -d
$seq ]; do seq=$
(( $seq + 1 )); done
148 case $kparam in *.new
) mv keepers.new keepers
;; esac
152 mkdir hack
; mv next hack
/current
; mv hack
/current .
; rmdir hack
154 ###----- That's all, folks --------------------------------------------------