ap->seq = htonl(peer->keynumber);
ap->key = htonl(keyid);
ap->siglen = 0;
- crypto_flags |= CRYPTO_FLAG_AUTO;
#if DEBUG
if (debug)
printf("make_keys: %d %08x %08x ts %u\n",
rval);
else
ap->siglen = htonl(len);
+ crypto_flags |= CRYPTO_FLAG_AUTO;
#endif /* PUBKEY */
}
int authlen; /* offset of MAC field */
int len; /* extension field length */
u_int code; /* extension field opcode */
- tstamp_t tstamp; /* extension field timestamp */
+ tstamp_t tstamp; /* timestamp */
+ tstamp_t fstamp; /* filestamp */
int i, rval;
u_int temp;
#ifdef PUBKEY
* been installed.
*/
case CRYPTO_PRIV:
+ poll_update(peer, peer->minpoll);
peer->cmmd = ntohl(pkt[i]);
/* fall through */
if (!crypto_flags)
break;
vp = (struct value *)&pkt[i + 2];
+ fstamp = ntohl(vp->fstamp);
temp = ntohl(vp->vallen);
kp = (R_RSA_PUBLIC_KEY *)peer->pubkey.ptr;
j = i + 5 + temp / 4;
rval = RV_PUB;
} else if (ntohl(pkt[j]) != kp->bits / 8) {
rval = RV_SIG;
- } else if (tstamp < ntohl(dhparam.tstamp) ||
- (tstamp == ntohl(dhparam.tstamp) &&
- (peer->flags & FLAG_AUTOKEY))) {
- rval = RV_TSP;
- } else if (tstamp <= ntohl(dhparam.fstamp) ||
- ntohl(vp->fstamp) < ntohl(dhparam.fstamp))
- {
+ } else if (tstamp < ntohl(dhparam.fstamp) ||
+ fstamp < ntohl(dhparam.fstamp)) {
+ rval = RV_FSP;
+ } else if (fstamp == ntohl(dhparam.fstamp) &&
+ (peer->flags & FLAG_AUTOKEY)) {
+ peer->crypto &= ~CRYPTO_FLAG_DH;
rval = RV_FSP;
} else {
R_VerifyInit(&ctx, DA_MD5);
if (debug)
printf(
"crypto_recv: verify %x parameters %u ts %u fs %u\n",
- rval, temp, tstamp,
- ntohl(vp->fstamp));
+ rval, temp, tstamp, fstamp);
#endif
+
+ /*
+ * If the peer data are newer than the host
+ * data, replace the host data. Otherwise,
+ * wait for the peer to fetch the host data.
+ */
if (rval != RV_OK || temp == 0) {
if (rval != RV_TSP)
msyslog(LOG_ERR,
"crypto: %x parameters %u ts %u fs %u\n",
- rval, temp, tstamp,
- ntohl(vp->fstamp));
+ rval, temp, tstamp, fstamp);
break;
}
peer->flash &= ~TEST10;
crypto_flags |= CRYPTO_FLAG_DH;
+ peer->crypto &= ~CRYPTO_FLAG_DH;
/*
* Initialize agreement parameters and extension
* parameters.
*/
case CRYPTO_DH:
+ poll_update(peer, peer->minpoll);
peer->cmmd = ntohl(pkt[i]);
if (!crypto_flags)
peer->cmmd |= CRYPTO_ERROR;
if (!crypto_flags)
break;
vp = (struct value *)&pkt[i + 2];
+ fstamp = ntohl(vp->fstamp);
temp = ntohl(vp->vallen);
kp = (R_RSA_PUBLIC_KEY *)peer->pubkey.ptr;
j = i + 5 + temp / 4;
*/
if (rval != RV_OK) {
temp = 0;
- } else if (ntohl(vp->fstamp) > dhparam.fstamp) {
- rval = RV_FSP;
+ } else if (fstamp > dhparam.fstamp) {
crypto_flags &= ~CRYPTO_FLAG_DH;
+ rval = RV_FSP;
} else {
rval = R_ComputeDHAgreedKey(dh_key,
(u_char *)&pkt[i + 5], dh_private,
printf(
"crypto_recv: verify %x agreement %08x ts %u (%u) fs %u\n",
rval, temp, tstamp,
- peer->pcookie.tstamp,
- ntohl(vp->fstamp));
+ peer->pcookie.tstamp, fstamp);
#endif
if (rval != RV_OK) {
if (rval != RV_TSP)
"crypto: %x agreement %08x ts %u (%u) fs %u\n",
rval, temp, tstamp,
peer->pcookie.tstamp,
- ntohl(vp->fstamp));
+ fstamp);
peer->cmmd |= CRYPTO_ERROR;
break;
}
if (!crypto_flags)
break;
vp = (struct value *)&pkt[i + 2];
+ fstamp = ntohl(vp->fstamp);
temp = ntohl(vp->vallen);
j = i + 5 + ntohl(vp->vallen) / 4;
bits = ntohl(pkt[i + 5]);
(tstamp == peer->pubkey.tstamp &&
(peer->flags & FLAG_AUTOKEY))) {
rval = RV_TSP;
- } else if (tstamp <= peer->pubkey.fstamp ||
- ntohl(vp->fstamp) < peer->pubkey.fstamp) {
+ } else if (tstamp < peer->pubkey.fstamp ||
+ fstamp < peer->pubkey.fstamp) {
+ rval = RV_FSP;
+ } else if (fstamp == peer->pubkey.fstamp &&
+ (peer->flags & FLAG_AUTOKEY)) {
rval = RV_FSP;
} else {
R_VerifyInit(&ctx, DA_MD5);
} else {
j = i + 5 + rsalen / 4;
peer->pubkey.ptr = (u_char *)kp;
- temp = strlen((char *)&pkt[j]);
+ temp = 1+ strlen((char *)&pkt[j]);
peer->keystr = emalloc(temp);
strcpy(peer->keystr,
(char *)&pkt[j]);
peer->pubkey.tstamp = tstamp;
- peer->pubkey.fstamp =
- ntohl(vp->fstamp);
+ peer->pubkey.fstamp = fstamp;
peer->flash &= ~TEST10;
}
}
printf(
"crypto_recv: verify %x host %s ts %u fs %u\n",
rval, (char *)&pkt[i + 5 + rsalen /
- 4], tstamp, ntohl(vp->fstamp));
+ 4], tstamp, fstamp);
#endif
if (rval != RV_OK) {
if (rval != RV_TSP)
"crypto: %x host %s ts %u fs %u\n",
rval, (char *)&pkt[i + 5 +
rsalen / 4], tstamp,
- ntohl(vp->fstamp));
+ fstamp);
}
break;
/*
if (!crypto_flags)
break;
vp = (struct value *)&pkt[i + 2];
+ fstamp = ntohl(vp->fstamp);
temp = ntohl(vp->vallen);
kp = (R_RSA_PUBLIC_KEY *)peer->pubkey.ptr;
j = i + 5 + temp / 4;
rval = RV_PUB;
} else if (ntohl(pkt[j]) != kp->bits / 8) {
rval = RV_SIG;
- } else if (tstamp < ntohl(tai_leap.tstamp) ||
- (tstamp == ntohl(tai_leap.tstamp) &&
- (peer->flags & FLAG_AUTOKEY))) {
- rval = RV_TSP;
- } else if (tstamp <= ntohl(tai_leap.fstamp) ||
- ntohl(vp->fstamp) < ntohl(tai_leap.fstamp))
- {
+ } else if (tstamp < ntohl(tai_leap.fstamp) ||
+ fstamp < ntohl(tai_leap.fstamp)) {
+ rval = RV_FSP;
+ } else if (fstamp == ntohl(tai_leap.fstamp) &&
+ (peer->flags & FLAG_AUTOKEY)) {
+ peer->crypto &= ~CRYPTO_FLAG_TAI;
rval = RV_FSP;
} else {
R_VerifyInit(&ctx, DA_MD5);
if (debug)
printf(
"crypto_recv: verify %x leapseconds %u ts %u fs %u\n",
- rval, temp, tstamp,
- ntohl(vp->fstamp));
+ rval, temp, tstamp, fstamp);
#endif
+
+ /*
+ * If the peer data are newer than the host
+ * data, replace the host data. Otherwise,
+ * wait for the peer to fetch the host data.
+ */
if (rval != RV_OK || temp == 0) {
if (rval != RV_TSP)
msyslog(LOG_ERR,
"crypto: %x leapseconds %u ts %u fs %u\n",
- rval, temp, tstamp,
- ntohl(vp->fstamp));
+ rval, temp, tstamp, fstamp);
break;
}
peer->flash &= ~TEST10;
crypto_flags |= CRYPTO_FLAG_TAI;
+ peer->crypto &= ~CRYPTO_FLAG_TAI;
sys_tai = temp / 4 + TAI_1972 - 1;
#ifdef KERNEL_PLL
#if NTP_API > 3
default:
if (code & (CRYPTO_RESP | CRYPTO_ERROR))
break;
+ poll_update(peer, peer->minpoll);
peer->cmmd = ntohl(pkt[i]);
break;
while (1) {
d = 1e9;
e = -1e9;
+ k = 0;
for (i = 0; i < nlist; i++) {
if (error[i] < d)
sendlen += crypto_xmit((u_int32 *)&xpkt,
sendlen, CRYPTO_NAME, peer->hcookie,
peer->assoc);
- else if (crypto_flags && !(crypto_flags &
- CRYPTO_FLAG_DH))
+ else if (crypto_flags && peer->crypto &
+ CRYPTO_FLAG_DH && sys_leap !=
+ LEAP_NOTINSYNC)
sendlen += crypto_xmit((u_int32 *)&xpkt,
sendlen, CRYPTO_DHPAR,
peer->hcookie, peer->assoc);
sendlen, CRYPTO_AUTO | CRYPTO_RESP,
peer->hcookie, peer->associd);
#ifdef PUBKEY
- else if (peer->crypto & CRYPTO_FLAG_TAI &&
- sys_tai == 0)
+ else if (peer->crypto & CRYPTO_FLAG_TAI)
sendlen += crypto_xmit((u_int32 *)&xpkt,
sendlen, CRYPTO_TAI, peer->hcookie,
peer->assoc);
sendlen, CRYPTO_AUTO, peer->hcookie,
peer->assoc);
#ifdef PUBKEY
- else if (peer->crypto & CRYPTO_FLAG_TAI &&
- sys_tai == 0)
+ else if (peer->crypto & CRYPTO_FLAG_TAI)
sendlen += crypto_xmit((u_int32 *)&xpkt,
sendlen, CRYPTO_TAI, peer->hcookie,
peer->assoc);
/*
* If extension fields are present, we must use a
- * private value of zero. Most intricate.
+ * private value of zero and force min poll interval.
+ * Most intricate.
*/
- if (sendlen > LEN_PKT_NOMAC)
+ if (sendlen > LEN_PKT_NOMAC) {
session_key(&peer->dstadr->sin, &peer->srcadr,
xkeyid, 0, 2);
+ poll_update(peer, peer->minpoll);
+ }
}
#endif /* AUTOKEY */
xkeyid = peer->keyid;