#643606 ssh-keygen: `-V' relative end-times -- implementation doesn't match manpage

Package:
openssh-client
Source:
openssh
Description:
secure shell (SSH) client, for secure access to remote machines
Submitter:
Mark Wooding
Date:
2011-09-28 00:15:04 UTC
Severity:
minor
#643606#5
Date:
2011-09-28 00:06:47 UTC
From:
To:
The manpage ssh-keygen.1 has this to say about the `-V' option.

     -V validity_interval
             Specify  a validity interval when signing a certificate.  A
             validity interval may consist of a single time,  indicating
             that the certificate is valid beginning now and expiring at
             that time, or may consist of two times separated by a colon
             to  indicate an explicit time interval.  The start time may
             be specified as a date in YYYYMMDD format, a time in YYYYM‐
             MDDHHMMSS  format  or a relative time (to the current time)
             consisting of a minus sign followed by a relative  time  in
             the  format  described  in  the  TIME  FORMATS  section  of
             sshd_config(5).  The end time may be specified as a  YYYYM‐
             MDD date, a YYYYMMDDHHMMSS time or a relative time starting
             with a plus character.

             For example: “+52w1d” (valid from now to 52 weeks  and  one
             day from now), “-4w:+4w” (valid from four weeks ago to four
             weeks  from  now),  “20100101123000:20110101123000”  (valid
             from  12:30 PM, January 1st, 2010 to 12:30 PM, January 1st,
             2011), “-1d:20110101” (valid from  yesterday  to  midnight,
             January 1st, 2011).

The source code, on the other hand, says this (ssh-keygen.c):

static void
parse_cert_times(char *timespec)
{
	char *from, *to;
	time_t now = time(NULL);
	int64_t secs;

	/* ... snip snip ... */

	if (*from == '-' || *from == '+')
		cert_valid_from = parse_relative_time(from, now);
	else
		cert_valid_from = parse_absolute_time(from);

	if (*to == '-' || *to == '+')
		cert_valid_to = parse_relative_time(to, cert_valid_from);
	else
		cert_valid_to = parse_absolute_time(to);

	if (cert_valid_to <= cert_valid_from)
		fatal("Empty certificate validity interval");
	xfree(from);
}

That is, the implementation interprets a relative end time with respect
to the start time, and not to the current time as stated quite clearly
in the manpage.

I'd submit a patch, but I don't know which of the documentation or the
implementation to fix (and besides, either way is very easy).  The
documented behaviour is more intuitive to me at least: it's what I
assumed would happen before I read the manpage to check (but now I've
found the discrepancy because SSH refused to accept my certificates).

But I'd guess changing the documentation is likely safer in the
following sense.  Since the start date is probably in the past, the
implementation will produce certificates that expire /early/ compared to
the documented behaviour.  Anyone out there who is assuming the
currently implemented behaviour would therefore, if it's changed to
match the manual, issue certificates with overly long validity periods.
(It would therefore suffice to change the parenthetical text `to the
current time' to `to the start time' and the example `-4w:+4w' to
`-4w:+8w'.)

(Severity `minor': there isn't a `very minor' -- it's easily worked
around if you know it's there, and certificates are a rather esoteric
feature anyway -- but there's definitely something wrong here so it's
not `wishlist'.)