3 ### Reveal shares of a secret distributed among keepers
5 ### (c) 2011 Mark Wooding
8 ###----- Licensing notice ---------------------------------------------------
10 ### This program is free software; you can redistribute it and/or modify
11 ### it under the terms of the GNU General Public License as published by
12 ### the Free Software Foundation; either version 2 of the License, or
13 ### (at your option) any later version.
15 ### This program is distributed in the hope that it will be useful,
16 ### but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ### GNU General Public License for more details.
20 ### You should have received a copy of the GNU General Public License
21 ### along with this program; if not, write to the Free Software Foundation,
22 ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 case "${KEYSLIB+t}" in t) ;; *) echo >&2 "$0: KEYSLIB unset"; exit 1 ;; esac
26 . "$KEYSLIB"/keyfunc.sh
30 Reveal a share of a recovery key distributed among keepers.
32 If enough shares have been revealed, reconstruct the recovery private key.
33 The key is read from KEY, or stdin if KEY is omitted or \`-'.
37 ## Parse the command line.
39 2) if [ -t 0 ]; then echo >&2 "$quis: stdin is a terminal"; exit 1; fi ;;
41 *) echo >&2 "$usage"; exit 1 ;;
43 recov=$1 keeper=$2; shift 2
45 *[!-0-9a-zA-Z_!%@+=/]* | */ | /* | \
46 *[!-0-9a-zA-Z_!%@+=]*/* | */*[!-0-9a-zA-Z_!%@+=]*)
47 echo >&2 "$quis: bad recovery key label \`$recov'"
55 checkword "keeper set label" "$keeper"
57 ## Grab the key, because we'll need to read it several times.
58 tmp=$(mktmp); cleanup rmtmp
60 pub=$(ec_public /dev/stdin <<EOF
65 ## Read the threshold from the recovery metadata.
66 read param <$KEYS/recov/$recov/$keeper.param
70 echo >&2 "$quis: secret sharing parameter file damaged (wrong header)"
78 echo >&2 "$quis: secret sharing parameter file damaged (missing t)"
85 ## Find out which keeper index it corresponds to.
86 read n hunoz <$KEYS/keeper/$keeper/meta
89 while [ $i -lt $n ]; do
90 read cand <$KEYS/keeper/$keeper/$i.pub
91 case "$pub" in "$cand") foundp=t; break ;; esac
95 nil) echo >&2 "$quis: key doesn't match keeper \`$keeper'"; exit 1 ;;
98 ## Establish the recovery staging area. See whether we've done enough
100 mem=$(userv root claim-mem-dir)
101 tag=$(echo $recov | tr / .)
102 if [ -d $mem/keys.reveal.$tag ]; then
103 echo >&2 "$quis: secret $recov already revealed"
106 reveal=$mem/keys.reveal.$tag.$keeper
107 if [ ! -d $reveal ]; then mkdir -m700 $reveal; fi
109 if [ -f share.$i ]; then
110 echo >&2 "$quis: share $i already revealed"
114 ## Decrypt the share.
115 ec_decrypt /dev/stdin \
116 -i$KEYS/recov/$recov/$keeper.$i.share \
120 mv share.$i.new share.$i
122 ## See if there's enough for a recovery.
124 for j in share.*; do if [ -f "$j" ]; then n=$(( n + 1 )); fi; done
125 if [ $n -lt $t ]; then
126 echo >&2 "$quis: share $i revealed; $(( t - n )) more required"
128 cat $KEYS/recov/$recov/$keeper.param share.* | shamir recover >secret
129 pubx=$(ec_public secret)
130 puby=$(cat $KEYS/recov/$recov/pub)
134 echo >&2 "quis: recovered secret key doesn't match public key"
139 mv keys.reveal.$tag.$keeper keys.reveal.$tag
140 echo >&2 "$quis: secret $recov revealed"
143 ###----- That's all, folks --------------------------------------------------