upstream: allow certificate validity intervals, sshsig verification
times and authorized_keys expiry-time options to accept dates in the UTC time zone in addition to the default of interpreting them in the system time zone. YYYYMMDD and YYMMDDHHMM[SS] dates/times will be interpreted as UTC if suffixed with a 'Z' character. Also allow certificate validity intervals to be specified in raw seconds-since-epoch as hex value, e.g. -V 0x1234:0x4567890. This is intended for use by regress tests and other tools that call ssh-keygen as part of a CA workflow. bz3468 ok dtucker OpenBSD-Commit-ID: 454db1cdffa9fa346aea5211223a2ce0588dfe13
This commit is contained in:
parent
4df246ec75
commit
ec1ddb72a1
26
misc.c
26
misc.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: misc.c,v 1.176 2022/06/03 04:30:47 djm Exp $ */
|
/* $OpenBSD: misc.c,v 1.177 2022/08/11 01:56:51 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||||
* Copyright (c) 2005-2020 Damien Miller. All rights reserved.
|
* Copyright (c) 2005-2020 Damien Miller. All rights reserved.
|
||||||
|
@ -2399,15 +2399,26 @@ parse_absolute_time(const char *s, uint64_t *tp)
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
time_t tt;
|
time_t tt;
|
||||||
char buf[32], *fmt;
|
char buf[32], *fmt;
|
||||||
|
const char *cp;
|
||||||
|
size_t l;
|
||||||
|
int is_utc = 0;
|
||||||
|
|
||||||
*tp = 0;
|
*tp = 0;
|
||||||
|
|
||||||
|
l = strlen(s);
|
||||||
|
if (l > 1 && strcasecmp(s + l - 1, "Z") == 0) {
|
||||||
|
is_utc = 1;
|
||||||
|
l--;
|
||||||
|
} else if (l > 3 && strcasecmp(s + l - 3, "UTC") == 0) {
|
||||||
|
is_utc = 1;
|
||||||
|
l -= 3;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* POSIX strptime says "The application shall ensure that there
|
* POSIX strptime says "The application shall ensure that there
|
||||||
* is white-space or other non-alphanumeric characters between
|
* is white-space or other non-alphanumeric characters between
|
||||||
* any two conversion specifications" so arrange things this way.
|
* any two conversion specifications" so arrange things this way.
|
||||||
*/
|
*/
|
||||||
switch (strlen(s)) {
|
switch (l) {
|
||||||
case 8: /* YYYYMMDD */
|
case 8: /* YYYYMMDD */
|
||||||
fmt = "%Y-%m-%d";
|
fmt = "%Y-%m-%d";
|
||||||
snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2s", s, s + 4, s + 6);
|
snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2s", s, s + 4, s + 6);
|
||||||
|
@ -2427,10 +2438,15 @@ parse_absolute_time(const char *s, uint64_t *tp)
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&tm, 0, sizeof(tm));
|
memset(&tm, 0, sizeof(tm));
|
||||||
if (strptime(buf, fmt, &tm) == NULL)
|
if ((cp = strptime(buf, fmt, &tm)) == NULL || *cp != '\0')
|
||||||
return SSH_ERR_INVALID_FORMAT;
|
|
||||||
if ((tt = mktime(&tm)) < 0)
|
|
||||||
return SSH_ERR_INVALID_FORMAT;
|
return SSH_ERR_INVALID_FORMAT;
|
||||||
|
if (is_utc) {
|
||||||
|
if ((tt = timegm(&tm)) < 0)
|
||||||
|
return SSH_ERR_INVALID_FORMAT;
|
||||||
|
} else {
|
||||||
|
if ((tt = mktime(&tm)) < 0)
|
||||||
|
return SSH_ERR_INVALID_FORMAT;
|
||||||
|
}
|
||||||
/* success */
|
/* success */
|
||||||
*tp = (uint64_t)tt;
|
*tp = (uint64_t)tt;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
88
ssh-keygen.1
88
ssh-keygen.1
|
@ -1,4 +1,4 @@
|
||||||
.\" $OpenBSD: ssh-keygen.1,v 1.223 2022/06/03 03:17:42 dtucker Exp $
|
.\" $OpenBSD: ssh-keygen.1,v 1.224 2022/08/11 01:56:51 djm Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
|
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: June 3 2022 $
|
.Dd $Mdocdate: August 11 2022 $
|
||||||
.Dt SSH-KEYGEN 1
|
.Dt SSH-KEYGEN 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -511,8 +511,11 @@ Print the full public key to standard output after signature verification.
|
||||||
.It Cm verify-time Ns = Ns Ar timestamp
|
.It Cm verify-time Ns = Ns Ar timestamp
|
||||||
Specifies a time to use when validating signatures instead of the current
|
Specifies a time to use when validating signatures instead of the current
|
||||||
time.
|
time.
|
||||||
The time may be specified as a date in YYYYMMDD format or a time
|
The time may be specified as a date or time in the YYYYMMDD[Z] or
|
||||||
in YYYYMMDDHHMM[SS] format.
|
in YYYYMMDDHHMM[SS][Z] formats.
|
||||||
|
Dates and times will be interpreted in the current system time zone unless
|
||||||
|
suffixed with a Z character, which causes them to be interpreted in the
|
||||||
|
UTC time zone.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
|
@ -603,31 +606,67 @@ 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
|
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.
|
of two times separated by a colon to indicate an explicit time interval.
|
||||||
.Pp
|
.Pp
|
||||||
The start time may be specified as the string
|
The start time may be specified as:
|
||||||
|
.Bl -bullet -compact
|
||||||
|
.It
|
||||||
|
The string
|
||||||
.Dq always
|
.Dq always
|
||||||
to indicate the certificate has no specified start time,
|
to indicate the certificate has no specified start time.
|
||||||
a date in YYYYMMDD format, a time in YYYYMMDDHHMM[SS] format,
|
.It
|
||||||
a relative time (to the current time) consisting of a minus sign followed by
|
A date or time in the system time zone formatted as YYYYMMDD or
|
||||||
an interval in the format described in the
|
YYYYMMDDHHMM[SS].
|
||||||
|
.It
|
||||||
|
A date or time in the UTC time zone as YYYYMMDDZ or YYYYMMDDHHMM[SS]Z.
|
||||||
|
.It
|
||||||
|
A relative time before the current system time consisting of a minus sign
|
||||||
|
followed by an interval in the format described in the
|
||||||
TIME FORMATS section of
|
TIME FORMATS section of
|
||||||
.Xr sshd_config 5 .
|
.Xr sshd_config 5 .
|
||||||
|
.It
|
||||||
|
A raw seconds since epoch (Jan 1 1970 00:00:00 UTC) as a hexadecimal
|
||||||
|
number beginning with
|
||||||
|
.Dq 0x .
|
||||||
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
The end time may be specified as a YYYYMMDD date, a YYYYMMDDHHMM[SS] time,
|
The end time may be specified similarly to the start time:
|
||||||
a relative time starting with a plus character or the string
|
.Bl -bullet -compact
|
||||||
|
.It
|
||||||
|
The string
|
||||||
.Dq forever
|
.Dq forever
|
||||||
to indicate that the certificate has no expiry date.
|
to indicate the certificate has no specified end time.
|
||||||
|
.It
|
||||||
|
A date or time in the system time zone formatted as YYYYMMDD or
|
||||||
|
YYYYMMDDHHMM[SS].
|
||||||
|
.It
|
||||||
|
A date or time in the UTC time zone as YYYYMMDDZ or YYYYMMDDHHMM[SS]Z.
|
||||||
|
.It
|
||||||
|
A relative time after the current system time consisting of a plus sign
|
||||||
|
followed by an interval in the format described in the
|
||||||
|
TIME FORMATS section of
|
||||||
|
.Xr sshd_config 5 .
|
||||||
|
.It
|
||||||
|
A raw seconds since epoch (Jan 1 1970 00:00:00 UTC) as a hexadecimal
|
||||||
|
number beginning with
|
||||||
|
.Dq 0x .
|
||||||
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
For example:
|
For example:
|
||||||
.Dq +52w1d
|
.Bl -tag -width Ds
|
||||||
(valid from now to 52 weeks and one day from now),
|
.It +52w1d
|
||||||
.Dq -4w:+4w
|
Valid from now to 52 weeks and one day from now.
|
||||||
(valid from four weeks ago to four weeks from now),
|
.It -4w:+4w
|
||||||
.Dq 20100101123000:20110101123000
|
Valid from four weeks ago to four weeks from now.
|
||||||
(valid from 12:30 PM, January 1st, 2010 to 12:30 PM, January 1st, 2011),
|
.It 20100101123000:20110101123000
|
||||||
.Dq -1d:20110101
|
Valid from 12:30 PM, January 1st, 2010 to 12:30 PM, January 1st, 2011.
|
||||||
(valid from yesterday to midnight, January 1st, 2011),
|
.It 20100101123000Z:20110101123000Z
|
||||||
.Dq -1m:forever
|
Similar, but interpreted in the UTC time zone rather than the system time zone.
|
||||||
(valid from one minute ago and never expiring).
|
.It -1d:20110101
|
||||||
|
Valid from yesterday to midnight, January 1st, 2011.
|
||||||
|
.It 0x1:0x2000000000
|
||||||
|
Valid from roughly early 1970 to May 2033.
|
||||||
|
.It -1m:forever
|
||||||
|
Valid from one minute ago and never expiring.
|
||||||
|
.El
|
||||||
.It Fl v
|
.It Fl v
|
||||||
Verbose mode.
|
Verbose mode.
|
||||||
Causes
|
Causes
|
||||||
|
@ -1206,7 +1245,10 @@ signature object and presented on the verification command-line must
|
||||||
match the specified list before the key will be considered acceptable.
|
match the specified list before the key will be considered acceptable.
|
||||||
.It Cm valid-after Ns = Ns "timestamp"
|
.It Cm valid-after Ns = Ns "timestamp"
|
||||||
Indicates that the key is valid for use at or after the specified timestamp,
|
Indicates that the key is valid for use at or after the specified timestamp,
|
||||||
which may be a date in YYYYMMDD format or a time in YYYYMMDDHHMM[SS] format.
|
which may be a date or time in the YYYYMMDD[Z] or YYYYMMDDHHMM[SS][Z] formats.
|
||||||
|
Dates and times will be interpreted in the current system time zone unless
|
||||||
|
suffixed with a Z character, which causes them to be interpreted in the UTC
|
||||||
|
time zone.
|
||||||
.It Cm valid-before Ns = Ns "timestamp"
|
.It Cm valid-before Ns = Ns "timestamp"
|
||||||
Indicates that the key is valid for use at or before the specified timestamp.
|
Indicates that the key is valid for use at or before the specified timestamp.
|
||||||
.El
|
.El
|
||||||
|
|
25
ssh-keygen.c
25
ssh-keygen.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: ssh-keygen.c,v 1.458 2022/08/05 05:01:40 djm Exp $ */
|
/* $OpenBSD: ssh-keygen.c,v 1.459 2022/08/11 01:56:51 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
|
@ -1916,6 +1916,21 @@ parse_relative_time(const char *s, time_t now)
|
||||||
return now + (u_int64_t)(secs * mul);
|
return now + (u_int64_t)(secs * mul);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_hex_u64(const char *s, uint64_t *up)
|
||||||
|
{
|
||||||
|
char *ep;
|
||||||
|
unsigned long long ull;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
ull = strtoull(s, &ep, 16);
|
||||||
|
if (*s == '\0' || *ep != '\0')
|
||||||
|
fatal("Invalid certificate time: not a number");
|
||||||
|
if (errno == ERANGE && ull == ULONG_MAX)
|
||||||
|
fatal_fr(SSH_ERR_SYSTEM_ERROR, "Invalid certificate time");
|
||||||
|
*up = (uint64_t)ull;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_cert_times(char *timespec)
|
parse_cert_times(char *timespec)
|
||||||
{
|
{
|
||||||
|
@ -1938,8 +1953,8 @@ parse_cert_times(char *timespec)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* from:to, where
|
* from:to, where
|
||||||
* from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | "always"
|
* from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | 0x... | "always"
|
||||||
* to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | "forever"
|
* to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | 0x... | "forever"
|
||||||
*/
|
*/
|
||||||
from = xstrdup(timespec);
|
from = xstrdup(timespec);
|
||||||
to = strchr(from, ':');
|
to = strchr(from, ':');
|
||||||
|
@ -1951,6 +1966,8 @@ parse_cert_times(char *timespec)
|
||||||
cert_valid_from = parse_relative_time(from, now);
|
cert_valid_from = parse_relative_time(from, now);
|
||||||
else if (strcmp(from, "always") == 0)
|
else if (strcmp(from, "always") == 0)
|
||||||
cert_valid_from = 0;
|
cert_valid_from = 0;
|
||||||
|
else if (strncmp(from, "0x", 2) == 0)
|
||||||
|
parse_hex_u64(from, &cert_valid_from);
|
||||||
else if (parse_absolute_time(from, &cert_valid_from) != 0)
|
else if (parse_absolute_time(from, &cert_valid_from) != 0)
|
||||||
fatal("Invalid from time \"%s\"", from);
|
fatal("Invalid from time \"%s\"", from);
|
||||||
|
|
||||||
|
@ -1958,6 +1975,8 @@ parse_cert_times(char *timespec)
|
||||||
cert_valid_to = parse_relative_time(to, now);
|
cert_valid_to = parse_relative_time(to, now);
|
||||||
else if (strcmp(to, "forever") == 0)
|
else if (strcmp(to, "forever") == 0)
|
||||||
cert_valid_to = ~(u_int64_t)0;
|
cert_valid_to = ~(u_int64_t)0;
|
||||||
|
else if (strncmp(from, "0x", 2) == 0)
|
||||||
|
parse_hex_u64(to, &cert_valid_to);
|
||||||
else if (parse_absolute_time(to, &cert_valid_to) != 0)
|
else if (parse_absolute_time(to, &cert_valid_to) != 0)
|
||||||
fatal("Invalid to time \"%s\"", to);
|
fatal("Invalid to time \"%s\"", to);
|
||||||
|
|
||||||
|
|
9
sshd.8
9
sshd.8
|
@ -33,8 +33,8 @@
|
||||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.\" $OpenBSD: sshd.8,v 1.319 2022/05/02 05:40:37 jmc Exp $
|
.\" $OpenBSD: sshd.8,v 1.320 2022/08/11 01:56:51 djm Exp $
|
||||||
.Dd $Mdocdate: May 2 2022 $
|
.Dd $Mdocdate: August 11 2022 $
|
||||||
.Dt SSHD 8
|
.Dt SSHD 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -533,8 +533,9 @@ controlled via the
|
||||||
option.
|
option.
|
||||||
.It Cm expiry-time="timespec"
|
.It Cm expiry-time="timespec"
|
||||||
Specifies a time after which the key will not be accepted.
|
Specifies a time after which the key will not be accepted.
|
||||||
The time may be specified as a YYYYMMDD date or a YYYYMMDDHHMM[SS] time
|
The time may be specified as a YYYYMMDD[Z] date or a YYYYMMDDHHMM[SS][Z] time.
|
||||||
in the system time-zone.
|
Dates and times will be interpreted in the system time zone unless suffixed
|
||||||
|
by a Z character, in which case they will be interpreted in the UTC time zone.
|
||||||
.It Cm from="pattern-list"
|
.It Cm from="pattern-list"
|
||||||
Specifies that in addition to public key authentication, either the canonical
|
Specifies that in addition to public key authentication, either the canonical
|
||||||
name of the remote host or its IP address must be present in the
|
name of the remote host or its IP address must be present in the
|
||||||
|
|
Loading…
Reference in New Issue