chiark / gitweb /
keyexch, keymgmt: Include the peer's public key in the check hash.
authorMark Wooding <mdw@distorted.org.uk>
Fri, 27 Oct 2006 16:55:27 +0000 (17:55 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Fri, 27 Oct 2006 16:55:27 +0000 (17:55 +0100)
This turns out to be necessary for security: otherwise an adversary can
cross over two sessions, which is probably undesirable.  This also
requires that we know our own public key, which was previously
unnecessary.

Except for session-ids (we don't care if two `sessions' with the same
peer get crossed over, because we don't distinguish them anyway), the
protocol now matches the one described and proved secure in the crypto
paper.

keyexch.c
keymgmt.c
tripe.h

index 80e0132a3bf9c69ccd86ca28325be7a39eba6957..f6786e0928b54dd7862f4686d8f9b034655f3645 100644 (file)
--- a/keyexch.c
+++ b/keyexch.c
@@ -47,7 +47,7 @@
  *
  * %$r_A = g^{\rho_A}$%                        Alice's challenge
  * %$c_A = H(\cookie{cookie}, r_A)$%   Alice's cookie
- * %$v_A = \rho_A \xor H(\cookie{expected-reply}, r_A, r_B, b^{\rho_A})$%
+ * %$v_A = \rho_A \xor H(\cookie{expected-reply}, a, r_A, r_B, b^{\rho_A})$%
  *                                     Alice's challenge check value
  * %$r_B^\alpha = a^{\rho_B}$%         Alice's reply
  * %$K = r_B^{\rho_A} = r_B^{\rho_A} = g^{\rho_A\rho_B}$%
@@ -415,6 +415,7 @@ static ge *getreply(keyexch *kx, ge *c, mp *ck)
   G_EXP(gg, r, c, kpriv);
   h = GH_INIT(algs.h);
   HASH_STRING(h, "tripe-expected-reply");
+  hashge(h, kx->kpub);
   hashge(h, c);
   hashge(h, kx->c);
   hashge(h, r);
@@ -427,8 +428,12 @@ static ge *getreply(keyexch *kx, ge *c, mp *ck)
     trace(T_CRYPTO, "crypto: recovered log = %s", mpstr(a));
   }))
   GH_DESTROY(h);
-  G_EXP(gg, y, gg->g, a);
-  ok = G_EQ(gg, y, c);
+  if (MP_CMP(a, >=, gg->r))
+    ok = 0;
+  else{
+    G_EXP(gg, y, gg->g, a);
+    ok = G_EQ(gg, y, c);
+  }
   if (!ok) {
     a_warn("KX", "?PEER", kx->p, "bad-expected-reply-log", A_END);
     IF_TRACING(T_KEYEXCH, IF_TRACING(T_CRYPTO, {
@@ -553,6 +558,7 @@ static int dochallenge(keyexch *kx, unsigned msg, buf *b)
 
     h = GH_INIT(algs.h);
     HASH_STRING(h, "tripe-expected-reply");
+    hashge(h, kpub);
     hashge(h, kx->c);
     hashge(h, kxc->c);
     hashge(h, kx->rx);
index 7163ddda5cd09720af6e4c15365ba0e81898972f..f645d1565a1de17fe7bbbb5374ae27b2513f8f36 100644 (file)
--- a/keymgmt.c
+++ b/keymgmt.c
@@ -34,6 +34,7 @@
 
 group *gg;
 mp *kpriv;
+ge *kpub;
 algswitch algs;
 
 /*----- Static variables --------------------------------------------------*/
@@ -398,6 +399,11 @@ tymatch:;
   if (kpriv)
     mp_drop(kpriv);
 
+  if (kpub)
+    G_DESTROY(g, kpub);
+  kpub = G_CREATE(g);
+  G_EXP(g, kpub, g->g, x);
+
   /* --- Dump out the group --- */
 
   IF_TRACING(T_KEYMGMT, {
diff --git a/tripe.h b/tripe.h
index 25255f321a3b0d7b4be556ef9867c97aecb3a048..5f62f16dbf51be863d9a7d18006cb5e226e44881 100644 (file)
--- a/tripe.h
+++ b/tripe.h
@@ -426,6 +426,7 @@ typedef struct admin {
 extern sel_state sel;                  /* Global I/O event state */
 extern group *gg;                      /* The group we work in */
 extern mp *kpriv;                      /* Our private key */
+extern ge *kpub;                       /* Our public key */
 extern octet buf_i[PKBUFSZ], buf_o[PKBUFSZ], buf_t[PKBUFSZ];
 extern const tunnel_ops *tunnels[];    /* Table of tunnels (0-term) */
 extern const tunnel_ops *tun_default;  /* Default tunnel to use */