. "$KEYSLIB"/keyfunc.sh
defhelp <<HELP
-RECOV [KEEPER:K ...]
+[-p PROFILE] RECOV [KEEPER:K ...] [-- OPTION=VALUE ...]
Generate a new recovery secret, and split it among the available keepers.
The new secret will be called RECOV. For each KEEPER set, the private key
If there is not a recovery key called RECOV then at least one keeper set must
be specified.
HELP
-dohelp
## Parse the command line.
-case $# in 0) echo >&2 "$usage"; exit 1 ;; esac
+profile=${recov_profile-recovery}
+while getopts "p:" opt; do
+ case "$opt" in
+ p) profile=$OPTARG ;;
+ *) usage_err ;;
+ esac
+done
+shift $(( $OPTIND - 1 ))
+case $# in 0) usage_err ;; esac
recov=$1; shift
checkword "recovery key label" "$recov"
+checkword "profile label" "$profile"
+nkeep=0
for k in "$@"; do
case "$k" in
+ --) break ;;
*:*) ;;
*) echo >&2 "$quis: bad keeper spec \`$k'"; exit 1 ;;
esac
- keeper=${k%:*} t=${k#*:}
+ keeper=${k%:*} t=${k#*:} nkeep=$(( $nkeep + 1 ))
checkword "keeper set label" "$keeper"
checknumber "keeper quorum" "$t"
done
## Establish the keeper parameters.
rdir=$KEYS/recov/$recov
if [ ! -d $rdir ]; then mkdir -m755 -p $rdir; fi
-case $# in
+case $nkeep in
0)
kparam=$rdir/keepers
;;
*)
for k in "$@"; do
+ case "$k" in --) break ;; esac
keeper=${k%:*} t=${k#*:}
echo $keeper $t
done >$rdir/keepers.new
if [ ! -f $kparam ]; then echo >&2 "$quis: no keepers specified"; exit 1; fi
## Make the new key and issue the shares.
-tmp=$(mktmp); cleanup rmtmp
+mktmp
rm -rf $rdir/new
mkdir -m755 $rdir/new
cd $tmp
-ec_keygen secret $rdir/new/pub
+while :; do case "$#,$1" in
+ 0,) break ;;
+ *,*,*) ;;
+ *,--) break ;;
+ esac
+ shift
+done
+c_gensyskey $profile $rdir/new/store secret recov="$recov"
while read keeper k; do
read n hunoz <$KEYS/keeper/$keeper/meta
shamir issue $k/$n secret | {
echo "$param" >$rdir/new/$keeper.param
i=0
while read share; do
- echo $share |
- ec_encrypt $KEYS/keeper/$keeper/$i.pub -o$rdir/new/$keeper.$i.share
- i=$(( i + 1 ))
+ c_sysencrypt $KEYS/keeper/$keeper/$i >$rdir/new/$keeper.$i.share <<EOF
+$share
+EOF
+ i=$(( $i + 1 ))
done
}
done <$kparam
seq=0
else
seq=$(readlink $rdir/current)
- mem=$(userv root claim-mem-dir </dev/null)
- reveal=$mem/keys.reveal/$recov.current/secret
+ reqsafe
+ reveal=$SAFE/keys.reveal/$recov.current/secret
if [ ! -f $reveal ]; then
echo >&2 "$quis: current $recov key not revealed"
exit 1
find $rdir/current/ -type f -name '*.recov' -print | while read name; do
name=${name#$rdir/current/}
case "$name" in */*) mkdir -p -m755 $rdir/new/${name%/*} ;; esac
- ec_decrypt $reveal -i$rdir/current/$name |
- ec_encrypt $rdir/new/pub -o$rdir/new/$name
+ c_sysdecrypt $rdir/current/store $reveal <$rdir/current/$name >tmp
+ c_sysencrypt $rdir/new/store <tmp >$rdir/new/$name
+ rm tmp
done
- rm -r $mem/keys.reveal/$recov.current
+ rm -r $SAFE/keys.reveal/$recov.current
fi
## Tidy up and commit. Repointing the symlink is grim because, according to
## symlink to a directory -- and there's no way of turning this behaviour
## off. The subterfuge here is due to Colin Watson.
cd $rdir
-while [ -d $seq ]; do seq=$(( seq + 1 )); done
+while [ -d $seq ]; do seq=$(( $seq + 1 )); done
case $kparam in *.new) mv keepers.new keepers ;; esac
rm -f next
ln -s $seq next