chiark / gitweb /
keys.new-keeper: Use `$quis' in errors, rather than `$0'.
[distorted-keys] / keys.reveal
CommitLineData
53263601
MW
1#! /bin/sh
2###
3### Reveal shares of a secret distributed among keepers
4###
5### (c) 2011 Mark Wooding
6###
7
8###----- Licensing notice ---------------------------------------------------
9###
599c8f75
MW
10### This file is part of the distorted.org.uk key management suite.
11###
12### distorted-keys is free software; you can redistribute it and/or modify
53263601
MW
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.
16###
599c8f75 17### distorted-keys is distributed in the hope that it will be useful,
53263601
MW
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.
21###
22### You should have received a copy of the GNU General Public License
599c8f75 23### along with distorted-keys; if not, write to the Free Software Foundation,
53263601
MW
24### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
26set -e
27case "${KEYSLIB+t}" in t) ;; *) echo >&2 "$0: KEYSLIB unset"; exit 1 ;; esac
28. "$KEYSLIB"/keyfunc.sh
29
30defhelp <<HELP
d516ebd0 31RECOV KEEPER
53263601
MW
32Reveal a share of a recovery key distributed among keepers.
33
34If enough shares have been revealed, reconstruct the recovery private key.
d516ebd0 35The keeper nub is read from stdin.
53263601 36HELP
53263601
MW
37
38## Parse the command line.
d516ebd0 39case $# in 2) ;; *) usage_err ;; esac
53263601 40recov=$1 keeper=$2; shift 2
599c8f75 41checklabel "recovery key" "$recov"
53263601 42case "$recov" in
599c8f75
MW
43 */*) ;;
44 *) recov=$recov/current ;;
53263601
MW
45esac
46checkword "keeper set label" "$keeper"
47
c47f2aba
MW
48## Check that this is a sensible thing to do.
49if [ ! -f $KEYS/keeper/$keeper/meta ]; then
50 echo >&2 "$quis: unknown keeper set \`$keeper'"
51 exit 1
52fi
53if [ ! -d $KEYS/recov/$recov ]; then
54 echo >&2 "$quis: unknown recovery key \`$recov'"
55 exit 1
56fi
57if [ ! -f $KEYS/recov/$recov/$keeper.param ]; then
58 echo >&2 "$quis: recovery key \`$recov' not kept by keeper set \`$keeper'"
59 exit 1
60fi
61
53263601 62## Grab the key, because we'll need to read it several times.
c47f2aba 63mktmp
d516ebd0 64cat >$tmp/secret
53263601
MW
65
66## Read the threshold from the recovery metadata.
67read param <$KEYS/recov/$recov/$keeper.param
68case "$param" in
69 shamir-params:*) ;;
70 *)
71 echo >&2 "$quis: secret sharing parameter file damaged (wrong header)"
72 exit 1
73 ;;
74esac
75t=";${param#*:}"
76case "$t" in
77 *";t="*) ;;
78 *)
79 echo >&2 "$quis: secret sharing parameter file damaged (missing t)"
80 exit 1
81 ;;
82esac
83t=${t#*;t=}
84t=${t%%;*}
85
86## Find out which keeper index it corresponds to.
87read n hunoz <$KEYS/keeper/$keeper/meta
88i=0
89foundp=nil
90while [ $i -lt $n ]; do
c47f2aba
MW
91 c_sysprepare $KEYS/keeper/$keeper/$i
92 nubbin=$(nubid <$tmp/secret)
93 nubid=$(cat $KEYS/keeper/$keeper/$i/nubid)
94 case "$nubbin" in "$nubid") foundp=t; break ;; esac
95 i=$(( $i + 1 ))
53263601
MW
96done
97case $foundp in
c47f2aba 98 nil) echo >&2 "$quis: nub doesn't match keeper \`$keeper'"; exit 1 ;;
53263601
MW
99esac
100
101## Establish the recovery staging area. See whether we've done enough
102## already.
c47f2aba 103reqsafe
53263601 104tag=$(echo $recov | tr / .)
c47f2aba
MW
105mkdir -p -m700 $SAFE/keys.reveal
106reveal=$SAFE/keys.reveal/$tag
599c8f75
MW
107if [ ! -d $reveal ]; then mkdir -m700 $reveal; fi
108cd $reveal
c47f2aba
MW
109if [ -f nub ]; then
110 echo >&2 "$quis: recovery key \`$recov' already revealed"
53263601
MW
111 exit 1
112fi
113
114## Decrypt the share.
599c8f75 115umask 077
c47f2aba
MW
116if [ -f $keeper.$i.share ]; then
117 echo >&2 "$quis: share $i already revealed"
118else
119 c_sysdecrypt $KEYS/keeper/$keeper/$i $tmp/secret \
120 <$KEYS/recov/$recov/$keeper.$i.share \
121 >$keeper.$i.new
122 mv $keeper.$i.new $keeper.$i.share
123fi
53263601
MW
124
125## See if there's enough for a recovery.
126n=0
c47f2aba 127for j in $keeper.*.share; do if [ -f "$j" ]; then n=$(( $n + 1 )); fi; done
53263601 128if [ $n -lt $t ]; then
c47f2aba 129 echo >&2 "$quis: share $i revealed; $(( $t - $n )) more required"
53263601 130else
c47f2aba 131 cat $KEYS/recov/$recov/$keeper.param $keeper.*.share >$keeper.shares
5c30c6e6 132 $bindir/shamir recover <$keeper.shares >nub.new
c47f2aba
MW
133 c_sysprepare $KEYS/recov/$recov/store
134 nubbin=$(nubid <nub.new)
135 nubid=$(cat $KEYS/recov/$recov/store/nubid)
136 case "$nubbin" in
137 "$nubid") ;;
53263601 138 *)
c47f2aba 139 echo >&2 "$quis: recovered nub doesn't match stored hash"
53263601
MW
140 exit 1
141 ;;
142 esac
c47f2aba
MW
143 mv nub.new nub
144 rm -f $keeper.*
145 echo >&2 "$quis: recovery key \`$recov' revealed"
53263601
MW
146fi
147
148###----- That's all, folks --------------------------------------------------