#define CONF_CRYPTO_CERT 4
#define CONF_CRYPTO_RAND 5
#define CONF_CRYPTO_KEYS 6
-#define CONF_CRYPTO_IFFPAR 7
-#define CONF_CRYPTO_GQPAR 8
-#define CONF_CRYPTO_MVPAR 9
-#define CONF_CRYPTO_PW 10
+#define CONF_CRYPTO_IDENT 7
+#define CONF_CRYPTO_IFFPAR 8
+#define CONF_CRYPTO_GQPAR 9
+#define CONF_CRYPTO_MVPAR 10
+#define CONF_CRYPTO_PW 11
#endif /* OPENSSL */
/*
#define CS_REVTIME 25
#define CS_LEAPTAB 26
#define CS_TAI 27
-#define CS_DIGEST 28
+#define CS_DIGEST 28
+#define CS_IDENT 29
#define CS_MAXCODE CS_DIGEST
#else
#define CS_MAXCODE CS_VARLIST
/*
* Flags used for certificate management
*/
-#define CERT_SIGN 0x01 /* certificate is signed */
-#define CERT_TRUST 0x02 /* certificate is trusted */
-#define CERT_PRIV 0x04 /* certificate is private */
+#define CERT_TRUST 0x01 /* certificate is trusted */
+#define CERT_SIGN 0x02 /* certificate is signed */
+#define CERT_VALID 0x04 /* certificate is valid */
+#define CERT_PRIV 0x08 /* certificate is private */
#define CERT_ERROR 0x80 /* certificate has errors */
/*
#define CRYPTO_CONF_GQPAR 9 /* GQ parameters file name */
#define CRYPTO_CONF_MVPAR 10 /* GQ parameters file name */
#define CRYPTO_CONF_PW 11 /* private key password */
+#define CRYPTO_CONF_IDENT 12 /* specify identity scheme */
/*
* Miscellaneous crypto stuff
#define NTP_AUTOMAX 13 /* log2 default max session key life */
#define KEY_REVOKE 16 /* log2 default key revoke timeout */
#define NTP_MAXEXTEN 1024 /* maximum extension field size */
+#define TAI_1972 10 /* initial TAI offset (s) */
/*
* The autokey structure holds the values used to authenticate key IDs.
extern struct value hostval; /* host name/value */
extern struct cert_info *cinfo; /* host certificate information */
extern struct value tai_leap; /* leapseconds table */
-extern u_int sys_tai; /* current UTC offset from TAI */
#endif /* OPENSSL */
extern void loop_config P((int, double));
extern void huffpuff P((void));
extern u_long sys_clocktime;
+extern u_long sys_tai;
/* ntp_monitor.c */
extern void init_mon P((void));
extern struct exten *crypto_args P((struct peer *, u_int, char *));
extern int crypto_public P((struct peer *, u_char *, u_int));
extern void value_free P((struct value *));
+extern char *iffpar_file;
+extern EVP_PKEY *iffpar_pkey;
+extern char *gqpar_file;
+extern EVP_PKEY *gqpar_pkey;
+extern char *mvpar_file;
+extern EVP_PKEY *mvpar_pkey;
+extern struct value tai_leap;
#endif /* OPENSSL */
/* ntp_proto.c */
{ "cert", CONF_CRYPTO_CERT },
{ "gqpar", CONF_CRYPTO_GQPAR },
{ "host", CONF_CRYPTO_RSA },
+ { "ident", CONF_CRYPTO_IDENT },
{ "iffpar", CONF_CRYPTO_IFFPAR },
{ "leap", CONF_CRYPTO_LEAP },
{ "mvpar", CONF_CRYPTO_MVPAR },
tokens[i]);
break;
+ case CONF_CRYPTO_IDENT:
+ crypto_config(CRYPTO_CONF_IDENT,
+ tokens[i]);
+ break;
+
case CONF_CRYPTO_IFFPAR:
crypto_config(CRYPTO_CONF_IFFPAR,
tokens[i]);
{ CS_PUBLIC, RO, "hostkey" }, /* 23 */
{ CS_CERTIF, RO, "cert" }, /* 24 */
{ CS_REVTIME, RO, "refresh" }, /* 25 */
- { CS_LEAPTAB, RO, "leapseconds" }, /* 26 */
+ { CS_LEAPTAB, RO, "leapsec" }, /* 26 */
{ CS_TAI, RO, "tai" }, /* 27 */
{ CS_DIGEST, RO, "signature" }, /* 28 */
+ { CS_IDENT, RO, "ident" }, /* 29 */
#endif /* OPENSSL */
- { 0, EOV, "" } /* 29 */
+ { 0, EOV, "" } /* 21/30 */
};
static struct ctl_var *ext_sys_var = (struct ctl_var *)0;
CS_FLAGS,
CS_PUBLIC,
CS_REVTIME,
+ CS_IDENT,
CS_LEAPTAB,
+ CS_TAI,
CS_CERTIF,
#endif /* OPENSSL */
0
ntohl(hostval.tstamp));
break;
+ case CS_IDENT:
+ if (iffpar_pkey != NULL)
+ ctl_putstr(sys_var[CS_IDENT].text,
+ iffpar_file, strlen(iffpar_file));
+ if (gqpar_pkey != NULL)
+ ctl_putstr(sys_var[CS_IDENT].text,
+ gqpar_file, strlen(gqpar_file));
+ if (mvpar_pkey != NULL)
+ ctl_putstr(sys_var[CS_IDENT].text,
+ mvpar_file, strlen(mvpar_file));
+ break;
+
case CS_LEAPTAB:
if (tai_leap.fstamp != 0)
ctl_putuint(sys_var[CS_LEAPTAB].text,
ntohl(tai_leap.fstamp));
- if (sys_tai != 0)
- ctl_putuint(sys_var[CS_TAI].text, sys_tai);
+ break;
+
+ case CS_TAI:
+ ctl_putuint(sys_var[CS_TAI].text, sys_tai);
break;
#endif /* OPENSSL */
}
* Global cryptodata in host byte order
*/
u_int32 crypto_flags = 0x0; /* status word */
-u_int sys_tai; /* current UTC offset from TAI */
/*
* Global cryptodata in network byte order
struct value hostval; /* host value */
struct value pubkey; /* public key */
struct value tai_leap; /* leapseconds table */
+EVP_PKEY *iffpar_pkey = NULL; /* IFF parameters */
+EVP_PKEY *gqpar_pkey = NULL; /* GQ parameters */
+EVP_PKEY *mvpar_pkey = NULL; /* MV parameters */
+char *iffpar_file = NULL; /* IFF parameters file */
+char *gqpar_file = NULL; /* GQ parameters file */
+char *mvpar_file = NULL; /* MV parameters file */
/*
* Private cryptodata in host byte order
static char *passwd = NULL; /* private key password */
static EVP_PKEY *host_pkey = NULL; /* host key */
static EVP_PKEY *sign_pkey = NULL; /* sign key */
-static EVP_PKEY *iffpar_pkey = NULL; /* IFF parameters */
-static EVP_PKEY *gqpar_pkey = NULL; /* GQ parameters */
-static EVP_PKEY *mvpar_pkey = NULL; /* MV parameters */
static const EVP_MD *sign_digest = NULL; /* sign digest */
static u_int sign_siglen; /* sign key length */
static char *rand_file = NULL; /* random seed file */
static char *host_file = NULL; /* host key file */
static char *sign_file = NULL; /* sign key file */
-static char *iffpar_file = NULL; /* IFF parameters file */
-static char *gqpar_file = NULL; /* GQ parameters file */
-static char *mvpar_file = NULL; /* MV parameters file */
static char *cert_file = NULL; /* certificate file */
static char *leap_file = NULL; /* leapseconds file */
static tstamp_t if_fstamp = 0; /* IFF file stamp */
tai_leap.ptr = emalloc(vallen);
memcpy(tai_leap.ptr, ep->pkt, vallen);
crypto_update();
- sys_tai = vallen / 4 + TAI_1972 - 1;
}
crypto_flags |= CRYPTO_FLAG_TAI;
peer->crypto |= CRYPTO_FLAG_LEAP;
peer->flash &= ~TEST8;
-#ifdef KERNEL_PLL
-#if NTP_API > 3
- /*
- * If the kernel cooperates, initialize the
- * current TAI offset.
- */
- ntv.modes = MOD_TAI;
- ntv.constant = sys_tai;
- (void)ntp_adjtime(&ntv);
-#endif /* NTP_API */
-#endif /* KERNEL_PLL */
sprintf(statstr, "leap %u ts %u fs %u",
vallen, ntohl(ep->tstamp),
ntohl(ep->fstamp));
struct peer *peer; /* peer structure pointer */
u_int opcode; /* extension field opcode */
struct exten *fp; /* extension pointers */
- struct cert_info *cp; /* certificate info/value pointer */
+ struct cert_info *cp, *xp; /* certificate info/value pointer */
char certname[MAXHOSTNAME + 1]; /* subject name buffer */
char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
u_int vallen;
memcpy(certname, ep->pkt, vallen);
certname[vallen] = '\0';
}
+
+ /*
+ * Find the self-signed, trusted certificate. If not
+ * found, use the first one found.
+ */
+ xp = NULL;
for (cp = cinfo; cp != NULL; cp = cp->link) {
if (cp->flags & CERT_PRIV)
continue;
if (strcmp(certname, cp->subject) == 0) {
- len += crypto_send(fp, &cp->cert);
- break;
+ if (xp == NULL)
+ xp = cp;
+ else if (strcmp(certname, cp->issuer) ==
+ 0 && cp->flags & CERT_TRUST)
+ xp = cp;
}
}
- if (cp == NULL)
+ if (xp == NULL)
opcode |= CRYPTO_ERROR;
+ else
+ len += crypto_send(fp, &xp->cert);
break;
/*
* this might result in a loop that could
* persist until timeout.
*/
- if (!(xp->flags & CERT_TRUST))
+ if (!(xp->flags & (CERT_TRUST | CERT_VALID)))
continue;
- yp->flags |= CERT_TRUST;
+ yp->flags |= CERT_VALID;
/*
* If subject Y matches the server subject name,
{
FILE *str; /* file handle */
char buf[NTP_MAXSTRLEN]; /* file line buffer */
- u_int leapsec[MAX_LEAP]; /* NTP time at leaps */
- u_int offset; /* offset at leap (s) */
+ u_int32 leapsec[MAX_LEAP]; /* NTP time at leaps */
+ int offset; /* offset at leap (s) */
char filename[MAXFILENAME]; /* name of leapseconds file */
char linkname[MAXFILENAME]; /* file link (for filestamp) */
char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
tstamp_t fstamp; /* filestamp */
u_int len;
- char *ptr;
- int rval, i;
-#ifdef KERNEL_PLL
-#if NTP_API > 3
- struct timex ntv; /* kernel interface structure */
-#endif /* NTP_API */
-#endif /* KERNEL_PLL */
+ u_int32 *ptr;
+ char *dp;
+ int rval, i, j;
/*
* Open the file and discard comment lines. If the first
rval = readlink(filename, linkname, MAXFILENAME - 1);
if (rval > 0) {
linkname[rval] = '\0';
- ptr = strrchr(linkname, '.');
+ dp = strrchr(linkname, '.');
} else {
- ptr = strrchr(filename, '.');
+ dp = strrchr(filename, '.');
}
- if (ptr != NULL)
- sscanf(++ptr, "%u", &fstamp);
+ if (dp != NULL)
+ sscanf(++dp, "%u", &fstamp);
else
fstamp = 0;
tai_leap.fstamp = htonl(fstamp);
*/
i = 0;
while (i < MAX_LEAP) {
- ptr = fgets(buf, NTP_MAXSTRLEN - 1, str);
- if (ptr == NULL)
+ dp = fgets(buf, NTP_MAXSTRLEN - 1, str);
+ if (dp == NULL)
break;
if (strlen(buf) < 1)
if (*buf == '#')
continue;
- if (sscanf(buf, "%u %u", &leapsec[i], &offset) != 2)
+ if (sscanf(buf, "%u %d", &leapsec[i], &offset) != 2)
continue;
- if (i != (int)(offset - TAI_1972)) {
+ if (i != offset - TAI_1972)
break;
- }
+
i++;
}
fclose(str);
- if (ptr != NULL) {
+ if (dp != NULL) {
msyslog(LOG_INFO,
"crypto_tai: leapseconds file %s error %d", cp,
rval);
/*
* The extension field table entries consists of the NTP seconds
- * of leap insertion in reverse order, so that the most recent
- * insertion is the first entry in the table.
+ * of leap insertion in network byte order.
*/
- len = i * 4;
+ len = i * sizeof(u_int32);
tai_leap.vallen = htonl(len);
ptr = emalloc(len);
tai_leap.ptr = (u_char *)ptr;
- for (; i >= 0; i--) {
- *ptr++ = (char) htonl(leapsec[i]);
- }
+ for (j = 0; j < i; j++)
+ *ptr++ = htonl(leapsec[j]);
crypto_flags |= CRYPTO_FLAG_TAI;
- sys_tai = len / 4 + TAI_1972 - 1;
-#ifdef KERNEL_PLL
-#if NTP_API > 3
- ntv.modes = MOD_TAI;
- ntv.constant = sys_tai;
- if (ntp_adjtime(&ntv) == TIME_ERROR)
- msyslog(LOG_INFO,
- "crypto_tai: kernel TAI update failed");
-#endif /* NTP_API */
-#endif /* KERNEL_PLL */
- sprintf(statstr, "%s link %d fs %u offset %u", cp, rval, fstamp,
- ntohl(tai_leap.vallen) / 4 + TAI_1972 - 1);
+ sprintf(statstr, "%s fs %u leap %u len %u", cp, fstamp,
+ leapsec[--j], len);
record_crypto_stats(NULL, statstr);
#ifdef DEBUG
if (debug)
* It the certificate is trusted, the subject must be the same
* as the issuer, in other words it must be self signed.
*/
- if (cinfo->flags & CERT_PRIV && strcmp(cinfo->subject,
+ if (cinfo->flags & CERT_TRUST && strcmp(cinfo->subject,
cinfo->issuer) != 0) {
if (cert_valid(cinfo, sign_pkey) != XEVNT_OK) {
msyslog(LOG_ERR,
strcpy(mvpar_file, cp);
break;
+ /*
+ * Set identity scheme.
+ */
+ case CRYPTO_CONF_IDENT:
+ if (!strcasecmp(cp, "iff"))
+ crypto_flags |= CRYPTO_FLAG_IFF;
+ else if (!strcasecmp(cp, "gq"))
+ crypto_flags |= CRYPTO_FLAG_GQ;
+ else if (!strcasecmp(cp, "mv"))
+ crypto_flags |= CRYPTO_FLAG_MV;
+ break;
+
/*
* Set certificate file name.
*/
double clock_stability; /* frequency stability (s/s) */
u_long sys_clocktime; /* last system clock update */
u_long pps_control; /* last pps update */
-
+u_long sys_tai; /* TAI offset from UTC (s) */
static void rstclock P((int, u_long, double)); /* transition function */
#ifdef KERNEL_PLL
*/
int
local_clock(
- struct peer *peer, /* synch source peer structure */
- double fp_offset /* clock offset (s) */
+ struct peer *peer, /* synch source peer structure */
+ double fp_offset /* clock offset (s) */
)
{
int rval; /* return code */
- u_long mu; /* interval since last update (s) */
- double flladj; /* FLL frequency adjustment (ppm) */
- double plladj; /* PLL frequency adjustment (ppm) */
- double clock_frequency; /* clock frequency adjustment (ppm) */
- double dtemp, etemp; /* double temps */
+ u_long mu; /* interval since last update (s) */
+ double flladj; /* FLL frequency adjustment (ppm) */
+ double plladj; /* PLL frequency adjustment (ppm) */
+ double clock_frequency; /* clock frequency adjustment (ppm) */
+ double dtemp, etemp; /* double temps */
+#ifdef OPENSSL
+ u_int32 *tpt;
+ int i;
+ u_int len;
+ long togo;
+#endif /* OPENSSL */
/*
* If the loop is opened, monitor and record the offsets
fp_offset);
reinit_timer();
tc_counter = 0;
+ sys_tai = 0;
rval = 2;
if (state == S_NSET) {
rstclock(S_FREQ, peer->epoch, 0);
rstclock(S_SYNC, peer->epoch, fp_offset);
}
+#ifdef OPENSSL
+ /*
+ * Scan the loopsecond table to determine the TAI offset. If
+ * there is a scheduled leap in future, set the leap warning.
+ */
+ tpt = (u_int32 *)tai_leap.ptr;
+ len = ntohl(tai_leap.vallen) / sizeof(u_int32);
+ if (tpt != NULL) {
+ for (i = 0; i < len; i++) {
+ togo = ntohl(tpt[i]) - peer->rec.l_ui;
+ if (togo > 0) {
+ sys_leap |= LEAP_ADDSECOND;
+ break;
+ }
+#ifdef STA_NANO
+ if (pll_control && kern_enable) {
+ memset(&ntv, 0, sizeof(ntv));
+ ntv.modes = MOD_BITS | MOD_TAI;
+ ntv.constant = i + TAI_1972 - 1;
+ ntp_adjtime(&ntv);
+ }
+#endif /* STA_NANO */
+ }
+ sys_tai = i + TAI_1972 - 1;
+ }
+#endif /* OPENSSL */
#ifdef KERNEL_PLL
/*
* This code segment works when clock adjustments are made using
int sys_authenticate; /* requre authentication for config */
l_fp sys_authdelay; /* authentication delay */
static u_long sys_authdly[2]; /* authentication delay shift reg */
-static u_char leap_consensus; /* consensus of survivor leap bits */
static double sys_mindisp = MINDISPERSE; /* min disp increment (s) */
static double sys_maxdist = MAXDISTANCE; /* selection threshold (s) */
double sys_jitter; /* system jitter (s) */
}
/*
- * Do not respond if unsynchronized or stratum is below
- * the floor or at or above the ceiling.
+ * Do not respond if stratum is below the floor.
*/
- if (hisleap == LEAP_NOTINSYNC || hisstratum <
- sys_floor || hisstratum >= sys_ceiling)
+ if (hisstratum < sys_floor)
return; /* bad stratum */
if ((peer = newpeer(&rbufp->recv_srcadr,
dtemp = sys_mindisp;
#endif /* REFCLOCK */
sys_rootdispersion = sys_peer->rootdispersion + dtemp;
- sys_leap = leap_consensus;
if (oleap == LEAP_NOTINSYNC) {
report_event(EVNT_SYNCCHG, NULL);
#ifdef OPENSSL
* stratum and that unsynchronized peers cannot survive this
* far.
*/
- leap_consensus = 0;
+ sys_leap = LEAP_NOWARNING;
for (i = 0; i < nlist; i++) {
peer = peer_list[i];
sys_survivors++;
- leap_consensus |= peer->leap;
+ sys_leap |= peer->leap;
peer->status = CTL_PST_SEL_SYNCCAND;
if (peer->flags & FLAG_PREFER)
sys_prefer = peer;
*
* Format 0 (22 ASCII printing characters):
*
- * <cr><lf>i ddd hh:mm:ss TZ=zz<cr><lf>
+ * <cr><lf>i ddd hh:mm:ss TZ=zz<cr><lf>
*
* on-time = first <cr>
* hh:mm:ss = hours, minutes, seconds