chiark / gitweb /
cryptop.verify: Use the correct operations.
[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
c47f2aba 31RECOV KEEPER [NUB]
53263601
MW
32Reveal a share of a recovery key distributed among keepers.
33
34If enough shares have been revealed, reconstruct the recovery private key.
c47f2aba 35The keeper nub is read from NUB, or stdin if NUB is omitted or \`-'.
53263601 36HELP
53263601
MW
37
38## Parse the command line.
39case $# in
40 2) if [ -t 0 ]; then echo >&2 "$quis: stdin is a terminal"; exit 1; fi ;;
41 3) ;;
c47f2aba 42 *) usage_err ;;
53263601
MW
43esac
44recov=$1 keeper=$2; shift 2
599c8f75 45checklabel "recovery key" "$recov"
53263601 46case "$recov" in
599c8f75
MW
47 */*) ;;
48 *) recov=$recov/current ;;
53263601
MW
49esac
50checkword "keeper set label" "$keeper"
51
c47f2aba
MW
52## Check that this is a sensible thing to do.
53if [ ! -f $KEYS/keeper/$keeper/meta ]; then
54 echo >&2 "$quis: unknown keeper set \`$keeper'"
55 exit 1
56fi
57if [ ! -d $KEYS/recov/$recov ]; then
58 echo >&2 "$quis: unknown recovery key \`$recov'"
59 exit 1
60fi
61if [ ! -f $KEYS/recov/$recov/$keeper.param ]; then
62 echo >&2 "$quis: recovery key \`$recov' not kept by keeper set \`$keeper'"
63 exit 1
64fi
65
53263601 66## Grab the key, because we'll need to read it several times.
c47f2aba
MW
67mktmp
68cat -- "$@" >$tmp/secret
53263601
MW
69
70## Read the threshold from the recovery metadata.
71read param <$KEYS/recov/$recov/$keeper.param
72case "$param" in
73 shamir-params:*) ;;
74 *)
75 echo >&2 "$quis: secret sharing parameter file damaged (wrong header)"
76 exit 1
77 ;;
78esac
79t=";${param#*:}"
80case "$t" in
81 *";t="*) ;;
82 *)
83 echo >&2 "$quis: secret sharing parameter file damaged (missing t)"
84 exit 1
85 ;;
86esac
87t=${t#*;t=}
88t=${t%%;*}
89
90## Find out which keeper index it corresponds to.
91read n hunoz <$KEYS/keeper/$keeper/meta
92i=0
93foundp=nil
94while [ $i -lt $n ]; do
c47f2aba
MW
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
99 i=$(( $i + 1 ))
53263601
MW
100done
101case $foundp in
c47f2aba 102 nil) echo >&2 "$quis: nub doesn't match keeper \`$keeper'"; exit 1 ;;
53263601
MW
103esac
104
105## Establish the recovery staging area. See whether we've done enough
106## already.
c47f2aba 107reqsafe
53263601 108tag=$(echo $recov | tr / .)
c47f2aba
MW
109mkdir -p -m700 $SAFE/keys.reveal
110reveal=$SAFE/keys.reveal/$tag
599c8f75
MW
111if [ ! -d $reveal ]; then mkdir -m700 $reveal; fi
112cd $reveal
c47f2aba
MW
113if [ -f nub ]; then
114 echo >&2 "$quis: recovery key \`$recov' already revealed"
53263601
MW
115 exit 1
116fi
117
118## Decrypt the share.
599c8f75 119umask 077
c47f2aba
MW
120if [ -f $keeper.$i.share ]; then
121 echo >&2 "$quis: share $i already revealed"
122else
123 c_sysdecrypt $KEYS/keeper/$keeper/$i $tmp/secret \
124 <$KEYS/recov/$recov/$keeper.$i.share \
125 >$keeper.$i.new
126 mv $keeper.$i.new $keeper.$i.share
127fi
53263601
MW
128
129## See if there's enough for a recovery.
130n=0
c47f2aba 131for j in $keeper.*.share; do if [ -f "$j" ]; then n=$(( $n + 1 )); fi; done
53263601 132if [ $n -lt $t ]; then
c47f2aba 133 echo >&2 "$quis: share $i revealed; $(( $t - $n )) more required"
53263601 134else
c47f2aba
MW
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)
140 case "$nubbin" in
141 "$nubid") ;;
53263601 142 *)
c47f2aba 143 echo >&2 "$quis: recovered nub doesn't match stored hash"
53263601
MW
144 exit 1
145 ;;
146 esac
c47f2aba
MW
147 mv nub.new nub
148 rm -f $keeper.*
149 echo >&2 "$quis: recovery key \`$recov' revealed"
53263601
MW
150fi
151
152###----- That's all, folks --------------------------------------------------