upstream commit

allow ssh-keygen to include arbitrary string or flag
certificate extensions and critical options. ok markus@ dtucker@

Upstream-ID: 2cf28dd6c5489eb9fc136e0b667ac3ea10241646
This commit is contained in:
djm@openbsd.org 2017-04-29 04:12:25 +00:00 committed by Damien Miller
parent 47a287bb6a
commit 249516e428
2 changed files with 60 additions and 5 deletions

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: ssh-keygen.1,v 1.133 2016/06/16 06:10:45 jmc Exp $
.\" $OpenBSD: ssh-keygen.1,v 1.134 2017/04/29 04:12:25 djm Exp $
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" 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
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd $Mdocdate: June 16 2016 $
.Dd $Mdocdate: April 29 2017 $
.Dt SSH-KEYGEN 1
.Os
.Sh NAME
@ -474,9 +474,29 @@ The
.Ar address_list
is a comma-separated list of one or more address/netmask pairs in CIDR
format.
.It Ic extension Ns : Ns Ar name Ns Op Ns = Ns Ar contents
Includes an arbitrary certificate extension.
.It Ic critical Ns : Ns Ar name Ns Op Ns = Ns Ar contents
Includes an arbitrary certificate critical option.
.El
.Pp
At present, no options are valid for host keys.
At present, no standard options are valid for host keys.
.Pp
For non-standard certificate extension or options included using
.Ic extension
or
.Ic option ,
the specified
.Ar name
should include a domain suffix, e.g.
.Dq name@example.com .
If a
.Ar contents
is specified then it is included as the contents of the extension/option
encoded as a string, otherwise the extension/option is created with no
contents (usually indicating a flag).
Extensions may be ignored by a client or server that does not recognise them,
whereas unknown critical options will cause the certificate to be refused.
.It Fl o
Causes
.Nm

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keygen.c,v 1.299 2017/03/10 04:26:06 djm Exp $ */
/* $OpenBSD: ssh-keygen.c,v 1.300 2017/04/29 04:12:25 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -149,6 +149,15 @@ u_int32_t certflags_flags = CERTOPT_DEFAULT;
char *certflags_command = NULL;
char *certflags_src_addr = NULL;
/* Arbitrary extensions specified by user */
struct cert_userext {
char *key;
char *val;
int crit;
};
struct cert_userext *cert_userext;
size_t ncert_userext;
/* Conversion to/from various formats */
int convert_to = 0;
int convert_from = 0;
@ -1531,6 +1540,8 @@ add_string_option(struct sshbuf *c, const char *name, const char *value)
static void
prepare_options_buf(struct sshbuf *c, int which)
{
size_t i;
sshbuf_reset(c);
if ((which & OPTIONS_CRITICAL) != 0 &&
certflags_command != NULL)
@ -1553,6 +1564,17 @@ prepare_options_buf(struct sshbuf *c, int which)
if ((which & OPTIONS_CRITICAL) != 0 &&
certflags_src_addr != NULL)
add_string_option(c, "source-address", certflags_src_addr);
for (i = 0; i < ncert_userext; i++) {
if ((cert_userext[i].crit && (which & OPTIONS_EXTENSIONS)) ||
(!cert_userext[i].crit && (which & OPTIONS_CRITICAL)))
continue;
if (cert_userext[i].val == NULL)
add_flag_option(c, cert_userext[i].key);
else {
add_string_option(c, cert_userext[i].key,
cert_userext[i].val);
}
}
}
static struct sshkey *
@ -1789,7 +1811,8 @@ parse_cert_times(char *timespec)
static void
add_cert_option(char *opt)
{
char *val;
char *val, *cp;
int iscrit = 0;
if (strcasecmp(opt, "clear") == 0)
certflags_flags = 0;
@ -1829,6 +1852,18 @@ add_cert_option(char *opt)
if (addr_match_cidr_list(NULL, val) != 0)
fatal("Invalid source-address list");
certflags_src_addr = xstrdup(val);
} else if (strncasecmp(opt, "extension:", 10) == 0 ||
(iscrit = (strncasecmp(opt, "critical:", 9) == 0))) {
val = xstrdup(strchr(opt, ':') + 1);
if ((cp = strchr(val, '=')) != NULL)
*cp++ = '\0';
cert_userext = xreallocarray(cert_userext, ncert_userext + 1,
sizeof(*cert_userext));
cert_userext[ncert_userext].key = val;
cert_userext[ncert_userext].val = cp == NULL ?
NULL : xstrdup(cp);
cert_userext[ncert_userext].crit = iscrit;
ncert_userext++;
} else
fatal("Unsupported certificate option \"%s\"", opt);
}