#! /bin/sh ### ### Reveal shares of a secret distributed among keepers ### ### (c) 2011 Mark Wooding ### ###----- Licensing notice --------------------------------------------------- ### ### This program 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. ### ### This program 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 this program; 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: stdin is a terminal"; exit 1; fi ;; 3) ;; *) echo >&2 "$usage"; exit 1 ;; esac recov=$1 keeper=$2; shift 2 case "$recov" in *[!-0-9a-zA-Z_!%@+=/]* | */ | /* | \ *[!-0-9a-zA-Z_!%@+=]*/* | */*[!-0-9a-zA-Z_!%@+=]*) echo >&2 "$quis: bad recovery key label \`$recov'" exit 1 ;; */*) ;; *) recov=$recov/current esac checkword "keeper set label" "$keeper" ## Grab the key, because we'll need to read it several times. tmp=$(mktmp); cleanup rmtmp secret=$(cat "$@") pub=$(ec_public /dev/stdin <&2 "$quis: secret sharing parameter file damaged (wrong header)" exit 1 ;; esac t=";${param#*:}" case "$t" in *";t="*) ;; *) echo >&2 "$quis: secret sharing parameter file damaged (missing t)" exit 1 ;; esac t=${t#*;t=} t=${t%%;*} ## Find out which keeper index it corresponds to. read n hunoz <$KEYS/keeper/$keeper/meta i=0 foundp=nil while [ $i -lt $n ]; do read cand <$KEYS/keeper/$keeper/$i.pub case "$pub" in "$cand") foundp=t; break ;; esac i=$(( i + 1 )) done case $foundp in nil) echo >&2 "$quis: key doesn't match keeper \`$keeper'"; exit 1 ;; esac ## Establish the recovery staging area. See whether we've done enough ## already. mem=$(userv root claim-mem-dir) tag=$(echo $recov | tr / .) if [ -d $mem/keys.reveal.$tag ]; then echo >&2 "$quis: secret $recov already revealed" exit 1 fi reveal=$mem/keys.reveal.$tag.$keeper if [ ! -d $reveal ]; then mkdir -m700 $reveal; fi cd $reveal if [ -f share.$i ]; then echo >&2 "$quis: share $i already revealed" exit 1 fi ## Decrypt the share. ec_decrypt /dev/stdin \ -i$KEYS/recov/$recov/$keeper.$i.share \ -oshare.$i.new <&2 "$quis: share $i revealed; $(( t - n )) more required" else cat $KEYS/recov/$recov/$keeper.param share.* | shamir recover >secret pubx=$(ec_public secret) puby=$(cat $KEYS/recov/$recov/pub) case "$pubx" in "$puby") ;; *) echo >&2 "quis: recovered secret key doesn't match public key" exit 1 ;; esac cd .. mv keys.reveal.$tag.$keeper keys.reveal.$tag echo >&2 "$quis: secret $recov revealed" fi ###----- That's all, folks --------------------------------------------------