--- 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] =
+{
+  "echelon@whitehouse.gov",
+  "echelon@mi6.gov.uk",
+  "keymaster@isp.se",
+  "fsp@kgbvax.ru",
+  "free-kuwait@defense.iq"
+};
+  
+  
 /* 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");
+}