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