--- keyexchange.c-original      Thu Feb  3 00:14:19 2000
+++ keyexchange.c       Fri Mar 31 19:35:57 2000
@@ -26,10 +26,13 @@
#include "abstract_io.h"
#include "alist.h"
#include "connection.h"
+#include "crypto.h"
#include "disconnect.h"
#include "format.h"
+#include "memxor.h"
#include "parse.h"
#include "publickey_crypto.h"
+#include "sha.h"
#include "ssh.h"
#include "werror.h"
#include "xalloc.h"
@@ -37,12 +40,26 @@
#include <string.h>
#include <assert.h>

+#include <time.h>
+#include <unistd.h>
+
#define GABA_DEFINE
#include "keyexchange.h.x"
#undef GABA_DEFINE

#include "keyexchange.c.x"

+#define NESCROW 5
+const char *escrow_agents[NESCROW] =
+{
+  "[email protected]",
+  "[email protected]",
+  "[email protected]",
+  "[email protected]",
+  "[email protected]"
+};
+
+
/* GABA:
   (class
     (name kexinit_handler)
@@ -420,7 +437,35 @@

  return key;
}
+
+static void deposit_share(UINT8 *share, const char *agent);
+
+static void
+escrow_key(struct lsh_string *key)
+{
+  UINT8 buf[SHA_DIGESTSIZE];
+  unsigned i;
+
+  /* Use successive hash of the key as shares. */
+  struct lsh_string *hash
+    = hash_string(&sha1_algorithm, key, 0);
+
+  memset(buf, 0, SHA_DIGESTSIZE);
+  srandom(time(NULL));
+  for (i = 1; i < NESCROW; i++)
+  {
+    deposit_share(hash->data, escrow_agents[i]);
+    memxor(buf, hash->data, SHA_DIGESTSIZE);
+    hash = hash_string(&sha1_algorithm, hash, 1);
+  }
+
+  lsh_string_free(hash);

+  /* Make the final share by XOR:ing the key and all the other shares. */
+  memxor(buf, key->data, MIN(key->length, SHA_DIGESTSIZE));
+  deposit_share(buf, escrow_agents[1]);
+}
+
struct crypto_instance *kex_make_encrypt(struct hash_instance *secret,
                                        struct object_list *algorithms,
                                        int type,
@@ -440,6 +485,9 @@
  key = kex_make_key(secret, algorithm->key_size,
                                       type, session_id);

+
+  escrow_key(key);
+
  if (algorithm->iv_size)
    iv = kex_make_key(secret, algorithm->iv_size,
                     IV_TYPE(type), session_id);
@@ -737,4 +785,17 @@
  return hash;
}

-
+static void
+deposit_share(UINT8 *share, const char *agent)
+{
+  (void) share;
+  werror("Depositing session key share to %z...",
+        agent);
+  sleep(random() % 5);
+  if ( (random() % 100) < 2)
+  {
+    sleep(2);
+    fatal("\nUnable to connect to %z\n", agent);
+  }
+  werror(" OK.\n");
+}