--- 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");
+}