summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ssh-keygen.126
-rw-r--r--ssh-keygen.c39
2 files changed, 60 insertions, 5 deletions
diff --git a/ssh-keygen.1 b/ssh-keygen.1
index ce2213c78..cfbd4cfa5 100644
--- a/ssh-keygen.1
+++ b/ssh-keygen.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-keygen.1,v 1.133 2016/06/16 06:10:45 jmc Exp $ 1.\" $OpenBSD: ssh-keygen.1,v 1.134 2017/04/29 04:12:25 djm Exp $
2.\" 2.\"
3.\" Author: Tatu Ylonen <ylo@cs.hut.fi> 3.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
4.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -35,7 +35,7 @@
35.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37.\" 37.\"
38.Dd $Mdocdate: June 16 2016 $ 38.Dd $Mdocdate: April 29 2017 $
39.Dt SSH-KEYGEN 1 39.Dt SSH-KEYGEN 1
40.Os 40.Os
41.Sh NAME 41.Sh NAME
@@ -474,9 +474,29 @@ The
474.Ar address_list 474.Ar address_list
475is a comma-separated list of one or more address/netmask pairs in CIDR 475is a comma-separated list of one or more address/netmask pairs in CIDR
476format. 476format.
477.It Ic extension Ns : Ns Ar name Ns Op Ns = Ns Ar contents
478Includes an arbitrary certificate extension.
479.It Ic critical Ns : Ns Ar name Ns Op Ns = Ns Ar contents
480Includes an arbitrary certificate critical option.
477.El 481.El
478.Pp 482.Pp
479At present, no options are valid for host keys. 483At present, no standard options are valid for host keys.
484.Pp
485For non-standard certificate extension or options included using
486.Ic extension
487or
488.Ic option ,
489the specified
490.Ar name
491should include a domain suffix, e.g.
492.Dq name@example.com .
493If a
494.Ar contents
495is specified then it is included as the contents of the extension/option
496encoded as a string, otherwise the extension/option is created with no
497contents (usually indicating a flag).
498Extensions may be ignored by a client or server that does not recognise them,
499whereas unknown critical options will cause the certificate to be refused.
480.It Fl o 500.It Fl o
481Causes 501Causes
482.Nm 502.Nm
diff --git a/ssh-keygen.c b/ssh-keygen.c
index f17af036b..c0d2d5942 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.299 2017/03/10 04:26:06 djm Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.300 2017/04/29 04:12:25 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -149,6 +149,15 @@ u_int32_t certflags_flags = CERTOPT_DEFAULT;
149char *certflags_command = NULL; 149char *certflags_command = NULL;
150char *certflags_src_addr = NULL; 150char *certflags_src_addr = NULL;
151 151
152/* Arbitrary extensions specified by user */
153struct cert_userext {
154 char *key;
155 char *val;
156 int crit;
157};
158struct cert_userext *cert_userext;
159size_t ncert_userext;
160
152/* Conversion to/from various formats */ 161/* Conversion to/from various formats */
153int convert_to = 0; 162int convert_to = 0;
154int convert_from = 0; 163int convert_from = 0;
@@ -1531,6 +1540,8 @@ add_string_option(struct sshbuf *c, const char *name, const char *value)
1531static void 1540static void
1532prepare_options_buf(struct sshbuf *c, int which) 1541prepare_options_buf(struct sshbuf *c, int which)
1533{ 1542{
1543 size_t i;
1544
1534 sshbuf_reset(c); 1545 sshbuf_reset(c);
1535 if ((which & OPTIONS_CRITICAL) != 0 && 1546 if ((which & OPTIONS_CRITICAL) != 0 &&
1536 certflags_command != NULL) 1547 certflags_command != NULL)
@@ -1553,6 +1564,17 @@ prepare_options_buf(struct sshbuf *c, int which)
1553 if ((which & OPTIONS_CRITICAL) != 0 && 1564 if ((which & OPTIONS_CRITICAL) != 0 &&
1554 certflags_src_addr != NULL) 1565 certflags_src_addr != NULL)
1555 add_string_option(c, "source-address", certflags_src_addr); 1566 add_string_option(c, "source-address", certflags_src_addr);
1567 for (i = 0; i < ncert_userext; i++) {
1568 if ((cert_userext[i].crit && (which & OPTIONS_EXTENSIONS)) ||
1569 (!cert_userext[i].crit && (which & OPTIONS_CRITICAL)))
1570 continue;
1571 if (cert_userext[i].val == NULL)
1572 add_flag_option(c, cert_userext[i].key);
1573 else {
1574 add_string_option(c, cert_userext[i].key,
1575 cert_userext[i].val);
1576 }
1577 }
1556} 1578}
1557 1579
1558static struct sshkey * 1580static struct sshkey *
@@ -1789,7 +1811,8 @@ parse_cert_times(char *timespec)
1789static void 1811static void
1790add_cert_option(char *opt) 1812add_cert_option(char *opt)
1791{ 1813{
1792 char *val; 1814 char *val, *cp;
1815 int iscrit = 0;
1793 1816
1794 if (strcasecmp(opt, "clear") == 0) 1817 if (strcasecmp(opt, "clear") == 0)
1795 certflags_flags = 0; 1818 certflags_flags = 0;
@@ -1829,6 +1852,18 @@ add_cert_option(char *opt)
1829 if (addr_match_cidr_list(NULL, val) != 0) 1852 if (addr_match_cidr_list(NULL, val) != 0)
1830 fatal("Invalid source-address list"); 1853 fatal("Invalid source-address list");
1831 certflags_src_addr = xstrdup(val); 1854 certflags_src_addr = xstrdup(val);
1855 } else if (strncasecmp(opt, "extension:", 10) == 0 ||
1856 (iscrit = (strncasecmp(opt, "critical:", 9) == 0))) {
1857 val = xstrdup(strchr(opt, ':') + 1);
1858 if ((cp = strchr(val, '=')) != NULL)
1859 *cp++ = '\0';
1860 cert_userext = xreallocarray(cert_userext, ncert_userext + 1,
1861 sizeof(*cert_userext));
1862 cert_userext[ncert_userext].key = val;
1863 cert_userext[ncert_userext].val = cp == NULL ?
1864 NULL : xstrdup(cp);
1865 cert_userext[ncert_userext].crit = iscrit;
1866 ncert_userext++;
1832 } else 1867 } else
1833 fatal("Unsupported certificate option \"%s\"", opt); 1868 fatal("Unsupported certificate option \"%s\"", opt);
1834} 1869}