3 ### Reveal shares of a secret distributed 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
32 Reveal a share of a recovery key distributed among keepers.
34 If enough shares have been revealed, reconstruct the recovery private key.
35 The key is read from KEY, or stdin if KEY is omitted or \`-'.
39 ## Parse the command line.
41 2) if [ -t 0 ]; then echo >&2 "$quis: stdin is a terminal"; exit 1; fi ;;
43 *) echo >&2 "$usage"; exit 1 ;;
45 recov=$1 keeper=$2; shift 2
46 checklabel "recovery key" "$recov"
49 *) recov=$recov/current ;;
51 checkword "keeper set label" "$keeper"
53 ## Grab the key, because we'll need to read it several times.
54 tmp=$(mktmp); cleanup rmtmp
56 pub=$(ec_public /dev/stdin <<EOF
61 ## Read the threshold from the recovery metadata.
62 read param <$KEYS/recov/$recov/$keeper.param
66 echo >&2 "$quis: secret sharing parameter file damaged (wrong header)"
74 echo >&2 "$quis: secret sharing parameter file damaged (missing t)"
81 ## Find out which keeper index it corresponds to.
82 read n hunoz <$KEYS/keeper/$keeper/meta
86 while [ $i -lt $n ]; do
87 read cand <$KEYS/keeper/$keeper/$i.pub
89 case "$pub" in "$cand") foundp=t; break ;; esac
93 nil) echo >&2 "$quis: key doesn't match keeper \`$keeper'"; exit 1 ;;
96 ## Establish the recovery staging area. See whether we've done enough
98 mem=$(userv root claim-mem-dir </dev/null)
99 tag=$(echo $recov | tr / .)
100 mkdir -p -m700 $mem/keys.reveal
101 reveal=$mem/keys.reveal/$tag
102 if [ ! -d $reveal ]; then mkdir -m700 $reveal; fi
104 if [ -f secret ]; then
105 echo >&2 "$quis: secret $recov already revealed"
108 if [ -f $keeper.$i ]; then
109 echo >&2 "$quis: share $i already revealed"
113 ## Decrypt the share.
115 ec_decrypt /dev/stdin \
116 -i$KEYS/recov/$recov/$keeper.$i.share \
117 -o$keeper.$i.new <<EOF
120 mv $keeper.$i.new $keeper.$i
122 ## See if there's enough for a recovery.
124 for j in $keeper.*; 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 $keeper.* >$keeper.shares
129 shamir recover <$keeper.shares >secret.new
130 pubx=$(ec_public secret.new)
131 puby=$(cat $KEYS/recov/$recov/pub)
135 echo >&2 "quis: recovered secret key doesn't match public key"
140 echo >&2 "$quis: secret $recov revealed"
143 ###----- That's all, folks --------------------------------------------------