/*
* Install association ID. This is used in multicast
- * client mode only only.
+ * client mode only.
*/
case CRYPTO_ASSOC | CRYPTO_RESP:
if (ntohl(pkt[i + 1]) != 0 && peer->flags &
/*
* Install autokey values in broadcast client and
- * symmetric modes.
+ * symmetric modes. Tricky here - discard old
+ * timestamps, but don't discard duplicate timestamps if
+ * the authentic bit is not set.
*/
case CRYPTO_AUTO | CRYPTO_RESP:
ap = (struct autokey *)&pkt[i + 2];
#ifdef PUBKEY
temp = ntohl(ap->siglen);
kp = (R_RSA_PUBLIC_KEY *)peer->pubkey;
- if (tstamp <= peer->recauto.tstamp) {
+ if (tstamp < peer->recauto.tstamp || (tstamp ==
+ peer->recauto.tstamp && peer->flags &
+ FLAG_AUTOKEY)) {
rval = RV_TSP;
} else if (!crypto_flags) {
rval = RV_OK;
(u_char *)ap->pkt, temp, kp);
}
#else /* PUBKEY */
- if (tstamp <= peer->recauto.tstamp)
+ if (tstamp <= peer->recauto.tstamp || (tstamp ==
+ peer->recauto.tstamp && peer->flags &
+ FLAG_AUTOKEY))
rval = RV_TSP;
else
rval = RV_OK;
break;
/*
- * Install session cookie in client and symmetric modes.
+ * Install session cookie in client mode. Use this also
+ * in symmetric modes when rsaref20 has not been
+ * installed for test.
*/
case CRYPTO_PRIV:
peer->cmmd = ntohl(pkt[i]);
#endif
if (rval != RV_OK || temp == 0)
break;
+ peer->flash &= ~TEST10;
/*
* Initialize Diffie-Hellman parameters and
#endif
if (rval != RV_OK || temp == 0)
break;
+ peer->flash &= ~TEST10;
/*
* Initialize TAI leapsecond table and extension
peer->flags &= ~FLAG_BURST;
peer->hmode = MODE_BCLIENT;
#ifdef AUTOKEY
- peer->pcookie.tstamp = 0;
key_expire(peer);
#endif /* AUTOKEY */
}
#ifdef PUBKEY
/*
* If the autokey boogie fails, the server may be bogus
- * or worse. Raise an alarm and rekey this thing.
+ * or worse. Raise an alarm and retrieve the autokey
+ * values again. If the server has in fact come up with
+ * new autokey values, this saves a timeout and general
+ * reset. On the other hand, an intruder could replay at
+ * speed packets from old associations with different
+ * cookies, which would cause needless server requests
+ * and burdensome responses. Since victim client sends a
+ * message only at poll intervals and victim server
+ * burns no PKI cycles, the attack doesn't do much harm.
*/
- if (peer->flash & TEST10) {
+ if (peer->flash & TEST10)
peer->flags &= ~FLAG_AUTOKEY;
- peer->recauto.tstamp = 0;
- }
if (!(peer->flags & FLAG_AUTOKEY))
peer->flash |= TEST11;
CRYPTO_RESP, peer->hcookie,
peer->associd);
if (!crypto_flags && peer->pcookie.tstamp ==
- 0 && peer->recauto.tstamp != 0 &&
- sys_leap != LEAP_NOTINSYNC)
+ 0 && sys_leap != LEAP_NOTINSYNC)
sendlen += crypto_xmit((u_int32 *)&xpkt,
sendlen, CRYPTO_PRIV, peer->hcookie,
peer->assoc);
sendlen, CRYPTO_DHPAR,
peer->hcookie, peer->assoc);
else if (crypto_flags && peer->pcookie.tstamp ==
- 0 && peer->recauto.tstamp != 0 &&
- sys_leap != LEAP_NOTINSYNC)
+ 0 && sys_leap != LEAP_NOTINSYNC)
sendlen += crypto_xmit((u_int32 *)&xpkt,
sendlen, CRYPTO_DH, peer->hcookie,
peer->assoc);
sendlen, (peer->cmmd >> 16) |
CRYPTO_RESP, peer->hcookie,
peer->associd);
- if (peer->pcookie.tstamp == 0 &&
- peer->recauto.tstamp != 0 && sys_leap !=
+ if (peer->pcookie.tstamp == 0 && sys_leap !=
LEAP_NOTINSYNC)
sendlen += crypto_xmit((u_int32 *)&xpkt,
sendlen, CRYPTO_PRIV, peer->hcookie,