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 keeper nub is read from NUB, or stdin if NUB is omitted or \`-'.
38 ## Parse the command line.
40 2) if [ -t
0 ]; then echo >&2 "$quis: stdin is a terminal"; exit 1; fi ;;
44 recov
=$1 keeper
=$2; shift 2
45 checklabel
"recovery key" "$recov"
48 *) recov
=$recov/current
;;
50 checkword
"keeper set label" "$keeper"
52 ## Check that this is a sensible thing to do.
53 if [ ! -f
$KEYS/keeper
/$keeper/meta
]; then
54 echo >&2 "$quis: unknown keeper set \`$keeper'"
57 if [ ! -d
$KEYS/recov
/$recov ]; then
58 echo >&2 "$quis: unknown recovery key \`$recov'"
61 if [ ! -f
$KEYS/recov
/$recov/$keeper.param
]; then
62 echo >&2 "$quis: recovery key \`$recov' not kept by keeper set \`$keeper'"
66 ## Grab the key, because we'll need to read it several times.
68 cat -- "$@" >$tmp/secret
70 ## Read the threshold from the recovery metadata.
71 read param
<$KEYS/recov
/$recov/$keeper.param
75 echo >&2 "$quis: secret sharing parameter file damaged (wrong header)"
83 echo >&2 "$quis: secret sharing parameter file damaged (missing t)"
90 ## Find out which keeper index it corresponds to.
91 read n hunoz
<$KEYS/keeper
/$keeper/meta
94 while [ $i -lt
$n ]; do
95 c_sysprepare
$KEYS/keeper
/$keeper/$i
96 nubbin
=$
(nubid
<$tmp/secret
)
97 nubid
=$
(cat $KEYS/keeper
/$keeper/$i/nubid
)
98 case "$nubbin" in "$nubid") foundp
=t
; break ;; esac
102 nil
) echo >&2 "$quis: nub doesn't match keeper \`$keeper'"; exit 1 ;;
105 ## Establish the recovery staging area. See whether we've done enough
108 tag
=$
(echo $recov |
tr / .
)
109 mkdir
-p
-m700
$SAFE/keys.reveal
110 reveal
=$SAFE/keys.reveal
/$tag
111 if [ ! -d
$reveal ]; then mkdir
-m700
$reveal; fi
114 echo >&2 "$quis: recovery key \`$recov' already revealed"
118 ## Decrypt the share.
120 if [ -f
$keeper.
$i.share
]; then
121 echo >&2 "$quis: share $i already revealed"
123 c_sysdecrypt
$KEYS/keeper
/$keeper/$i $tmp/secret \
124 <$KEYS/recov
/$recov/$keeper.
$i.share \
126 mv $keeper.
$i.new
$keeper.
$i.share
129 ## See if there's enough for a recovery.
131 for j
in $keeper.
*.share
; do if [ -f
"$j" ]; then n
=$
(( $n + 1 )); fi; done
132 if [ $n -lt
$t ]; then
133 echo >&2 "$quis: share $i revealed; $(( $t - $n )) more required"
135 cat $KEYS/recov
/$recov/$keeper.param
$keeper.
*.share
>$keeper.shares
136 shamir recover
<$keeper.shares
>nub.new
137 c_sysprepare
$KEYS/recov
/$recov/store
138 nubbin
=$
(nubid
<nub.new
)
139 nubid
=$
(cat $KEYS/recov
/$recov/store
/nubid
)
143 echo >&2 "$quis: recovered nub doesn't match stored hash"
149 echo >&2 "$quis: recovery key \`$recov' revealed"
152 ###----- That's all, folks --------------------------------------------------