#! /bin/sh ### ### Reveal shares of a secret distributed among keepers ### ### (c) 2011 Mark Wooding ### ###----- Licensing notice --------------------------------------------------- ### ### This file is part of the distorted.org.uk key management suite. ### ### distorted-keys is free software; you can redistribute it and/or modify ### it under the terms of the GNU General Public License as published by ### the Free Software Foundation; either version 2 of the License, or ### (at your option) any later version. ### ### distorted-keys is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with distorted-keys; if not, write to the Free Software Foundation, ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. set -e case "${KEYSLIB+t}" in t) ;; *) echo >&2 "$0: KEYSLIB unset"; exit 1 ;; esac . "$KEYSLIB"/keyfunc.sh defhelp <&2 "$quis: unknown keeper set \`$keeper'" exit 1 fi if [ ! -h $KEYS/recov/$recov/current ]; then echo >&2 "$quis: unknown recovery key \`$recov'" exit 1 fi rdir=$KEYS/recov/$recov/$inst if [ ! -f $rdir/$keeper.param ]; then echo >&2 "$quis: recovery key \`$recov' not kept by keeper set \`$keeper'" exit 1 fi ## Grab the key, because we'll need to read it several times. mktmp cat >$tmp/secret ## Read the threshold from the recovery metadata. t=$(sharethresh $rdir/$keeper.param) ## Find out which keeper index it corresponds to. read n hunoz <$keepdir/meta i=0 foundnubp=nil while [ $i -lt $n ]; do c_sysprepare $keepdir/$i nubbin=$(nubid <$tmp/secret) nubid=$(cat $keepdir/$i/nubid) case "$nubbin" in "$nubid") foundnubp=t; break ;; esac i=$(( $i + 1 )) done case $foundnubp in nil) echo >&2 "$quis: nub doesn't match keeper \`$keeper'"; exit 1 ;; esac ## Establish the recovery staging area. See whether we've done enough ## already. reqsafe tag=$recov.$inst mkdir -p -m700 $SAFE/keys.reveal reveal=$SAFE/keys.reveal/$tag if [ ! -d $reveal ]; then mkdir -m700 $reveal; fi cd $reveal if [ -f nub ]; then echo >&2 "$quis: recovery key \`$recov/$inst' already revealed" exit 1 fi ## Decrypt the share. umask 077 if [ -f $keeper.$i.share ]; then echo >&2 "$quis: share $i already revealed" else c_sysdecrypt $keepdir/$i $tmp/secret \ <$rdir/$keeper.$i.share \ >$keeper.$i.new mv $keeper.$i.new $keeper.$i.share fi ## See if there's enough for a recovery. n=0 for j in $keeper.*.share; do if [ -f "$j" ]; then n=$(( $n + 1 )); fi; done if [ $n -lt $t ]; then echo >&2 "$quis: share $i revealed; $(( $t - $n )) more required" else cat $rdir/$keeper.param $keeper.*.share >$keeper.shares $bindir/shamir recover <$keeper.shares >nub.new c_sysprepare $rdir/store nubbin=$(nubid &2 "$quis: recovered nub doesn't match stored hash" exit 1 ;; esac mv nub.new nub rm -f $keeper.* echo >&2 "$quis: recovery key \`$recov/$inst' revealed" fi ###----- That's all, folks --------------------------------------------------