chiark / gitweb /
Multiple key types, key profiles, and user key storage.
[distorted-keys] / keys.new-recov
similarity index 79%
rename from new-recov
rename to keys.new-recov
index d221764..c5d7fce 100755 (executable)
--- a/new-recov
@@ -28,7 +28,7 @@ case "${KEYSLIB+t}" in t) ;; *) echo >&2 "$0: KEYSLIB unset"; exit 1 ;; esac
 . "$KEYSLIB"/keyfunc.sh
 
 defhelp <<HELP
-RECOV [KEEPER:K ...]
+[-p PROFILE] RECOV [KEEPER:K ...] [-- OPTION=VALUE ...]
 Generate a new recovery secret, and split it among the available keepers.
 
 The new secret will be called RECOV.  For each KEEPER set, the private key
@@ -43,18 +43,28 @@ used.
 If there is not a recovery key called RECOV then at least one keeper set must
 be specified.
 HELP
-dohelp
 
 ## Parse the command line.
-case $# in 0) echo >&2 "$usage"; exit 1 ;; esac
+profile=${recov_profile-recovery}
+while getopts "p:" opt; do
+  case "$opt" in
+    p) profile=$OPTARG ;;
+    *) usage_err ;;
+  esac
+done
+shift $(( $OPTIND - 1 ))
+case $# in 0) usage_err ;; esac
 recov=$1; shift
 checkword "recovery key label" "$recov"
+checkword "profile label" "$profile"
+nkeep=0
 for k in "$@"; do
   case "$k" in
+    --) break ;;
     *:*) ;;
     *) echo >&2 "$quis: bad keeper spec \`$k'"; exit 1 ;;
   esac
-  keeper=${k%:*} t=${k#*:}
+  keeper=${k%:*} t=${k#*:} nkeep=$(( $nkeep + 1 ))
   checkword "keeper set label" "$keeper"
   checknumber "keeper quorum" "$t"
 done
@@ -62,12 +72,13 @@ done
 ## Establish the keeper parameters.
 rdir=$KEYS/recov/$recov
 if [ ! -d $rdir ]; then mkdir -m755 -p $rdir; fi
-case $# in
+case $nkeep in
   0)
     kparam=$rdir/keepers
     ;;
   *)
     for k in "$@"; do
+      case "$k" in --) break ;; esac
       keeper=${k%:*} t=${k#*:}
       echo $keeper $t
     done >$rdir/keepers.new
@@ -77,11 +88,18 @@ esac
 if [ ! -f $kparam ]; then echo >&2 "$quis: no keepers specified"; exit 1; fi
 
 ## Make the new key and issue the shares.
-tmp=$(mktmp); cleanup rmtmp
+mktmp
 rm -rf $rdir/new
 mkdir -m755 $rdir/new
 cd $tmp
-ec_keygen secret $rdir/new/pub
+while :; do case "$#,$1" in
+    0,) break ;;
+    *,*,*) ;;
+    *,--) break ;;
+  esac
+  shift
+done
+c_gensyskey $profile $rdir/new/store secret recov="$recov"
 while read keeper k; do
   read n hunoz <$KEYS/keeper/$keeper/meta
   shamir issue $k/$n secret | {
@@ -89,9 +107,10 @@ while read keeper k; do
     echo "$param" >$rdir/new/$keeper.param
     i=0
     while read share; do
-      echo $share |
-       ec_encrypt $KEYS/keeper/$keeper/$i.pub -o$rdir/new/$keeper.$i.share
-      i=$(( i + 1 ))
+      c_sysencrypt $KEYS/keeper/$keeper/$i >$rdir/new/$keeper.$i.share <<EOF
+$share
+EOF
+      i=$(( $i + 1 ))
     done
   }
 done <$kparam
@@ -102,8 +121,8 @@ if [ ! -d $rdir/current ]; then
   seq=0
 else
   seq=$(readlink $rdir/current)
-  mem=$(userv root claim-mem-dir </dev/null)
-  reveal=$mem/keys.reveal/$recov.current/secret
+  reqsafe
+  reveal=$SAFE/keys.reveal/$recov.current/secret
   if [ ! -f $reveal ]; then
     echo >&2 "$quis: current $recov key not revealed"
     exit 1
@@ -112,10 +131,11 @@ else
   find $rdir/current/ -type f -name '*.recov' -print | while read name; do
     name=${name#$rdir/current/}
     case "$name" in */*) mkdir -p -m755 $rdir/new/${name%/*} ;; esac
-    ec_decrypt $reveal -i$rdir/current/$name |
-      ec_encrypt $rdir/new/pub -o$rdir/new/$name
+    c_sysdecrypt $rdir/current/store $reveal <$rdir/current/$name >tmp
+    c_sysencrypt $rdir/new/store <tmp >$rdir/new/$name
+    rm tmp
   done
-  rm -r $mem/keys.reveal/$recov.current
+  rm -r $SAFE/keys.reveal/$recov.current
 fi
 
 ## Tidy up and commit.  Repointing the symlink is grim because, according to
@@ -123,7 +143,7 @@ fi
 ## symlink to a directory -- and there's no way of turning this behaviour
 ## off.  The subterfuge here is due to Colin Watson.
 cd $rdir
-while [ -d $seq ]; do seq=$(( seq + 1 )); done
+while [ -d $seq ]; do seq=$(( $seq + 1 )); done
 case $kparam in *.new) mv keepers.new keepers ;; esac
 rm -f next
 ln -s $seq next