-.\" $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
.\" (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
.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
-/* $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
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;
static void
prepare_options_buf(struct sshbuf *c, int which)
{
+ size_t i;
+
sshbuf_reset(c);
if ((which & OPTIONS_CRITICAL) != 0 &&
certflags_command != NULL)
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 *
static void
add_cert_option(char *opt)
{
- char *val;
+ char *val, *cp;
+ int iscrit = 0;
if (strcasecmp(opt, "clear") == 0)
certflags_flags = 0;
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);
}