diff options
-rw-r--r-- | ssh-keygen.1 | 26 | ||||
-rw-r--r-- | ssh-keygen.c | 39 |
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 |
475 | is a comma-separated list of one or more address/netmask pairs in CIDR | 475 | is a comma-separated list of one or more address/netmask pairs in CIDR |
476 | format. | 476 | format. |
477 | .It Ic extension Ns : Ns Ar name Ns Op Ns = Ns Ar contents | ||
478 | Includes an arbitrary certificate extension. | ||
479 | .It Ic critical Ns : Ns Ar name Ns Op Ns = Ns Ar contents | ||
480 | Includes an arbitrary certificate critical option. | ||
477 | .El | 481 | .El |
478 | .Pp | 482 | .Pp |
479 | At present, no options are valid for host keys. | 483 | At present, no standard options are valid for host keys. |
484 | .Pp | ||
485 | For non-standard certificate extension or options included using | ||
486 | .Ic extension | ||
487 | or | ||
488 | .Ic option , | ||
489 | the specified | ||
490 | .Ar name | ||
491 | should include a domain suffix, e.g. | ||
492 | .Dq name@example.com . | ||
493 | If a | ||
494 | .Ar contents | ||
495 | is specified then it is included as the contents of the extension/option | ||
496 | encoded as a string, otherwise the extension/option is created with no | ||
497 | contents (usually indicating a flag). | ||
498 | Extensions may be ignored by a client or server that does not recognise them, | ||
499 | whereas unknown critical options will cause the certificate to be refused. | ||
480 | .It Fl o | 500 | .It Fl o |
481 | Causes | 501 | Causes |
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; | |||
149 | char *certflags_command = NULL; | 149 | char *certflags_command = NULL; |
150 | char *certflags_src_addr = NULL; | 150 | char *certflags_src_addr = NULL; |
151 | 151 | ||
152 | /* Arbitrary extensions specified by user */ | ||
153 | struct cert_userext { | ||
154 | char *key; | ||
155 | char *val; | ||
156 | int crit; | ||
157 | }; | ||
158 | struct cert_userext *cert_userext; | ||
159 | size_t ncert_userext; | ||
160 | |||
152 | /* Conversion to/from various formats */ | 161 | /* Conversion to/from various formats */ |
153 | int convert_to = 0; | 162 | int convert_to = 0; |
154 | int convert_from = 0; | 163 | int convert_from = 0; |
@@ -1531,6 +1540,8 @@ add_string_option(struct sshbuf *c, const char *name, const char *value) | |||
1531 | static void | 1540 | static void |
1532 | prepare_options_buf(struct sshbuf *c, int which) | 1541 | prepare_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 | ||
1558 | static struct sshkey * | 1580 | static struct sshkey * |
@@ -1789,7 +1811,8 @@ parse_cert_times(char *timespec) | |||
1789 | static void | 1811 | static void |
1790 | add_cert_option(char *opt) | 1812 | add_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 | } |