diff options
author | djm@openbsd.org <djm@openbsd.org> | 2018-09-20 03:30:44 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2018-09-20 14:00:29 +1000 |
commit | ecac7e1f7add6b28874959a11f2238d149dc2c07 (patch) | |
tree | 58cde218f604646101ff838423b7beeafb46b909 | |
parent | 86e5737c39153af134158f24d0cab5827cbd5852 (diff) |
upstream: add CASignatureAlgorithms option for the client, allowing
it to specify which signature algorithms may be used by CAs when signing
certificates. Useful if you want to ban RSA/SHA1; ok markus@
OpenBSD-Commit-ID: 9159e5e9f67504829bf53ff222057307a6e3230f
-rw-r--r-- | readconf.c | 16 | ||||
-rw-r--r-- | readconf.h | 3 | ||||
-rw-r--r-- | ssh_config.5 | 16 | ||||
-rw-r--r-- | sshconnect.c | 17 |
4 files changed, 42 insertions, 10 deletions
diff --git a/readconf.c b/readconf.c index db5f2d547..057726d0e 100644 --- a/readconf.c +++ b/readconf.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.c,v 1.297 2018/08/12 20:19:13 djm Exp $ */ | 1 | /* $OpenBSD: readconf.c,v 1.298 2018/09/20 03:30:44 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 |
@@ -172,7 +172,7 @@ typedef enum { | |||
172 | oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, | 172 | oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, |
173 | oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, | 173 | oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, |
174 | oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes, | 174 | oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes, |
175 | oPubkeyAcceptedKeyTypes, oProxyJump, | 175 | oPubkeyAcceptedKeyTypes, oCASignatureAlgorithms, oProxyJump, |
176 | oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported | 176 | oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported |
177 | } OpCodes; | 177 | } OpCodes; |
178 | 178 | ||
@@ -266,6 +266,7 @@ static struct { | |||
266 | { "dynamicforward", oDynamicForward }, | 266 | { "dynamicforward", oDynamicForward }, |
267 | { "preferredauthentications", oPreferredAuthentications }, | 267 | { "preferredauthentications", oPreferredAuthentications }, |
268 | { "hostkeyalgorithms", oHostKeyAlgorithms }, | 268 | { "hostkeyalgorithms", oHostKeyAlgorithms }, |
269 | { "casignaturealgorithms", oCASignatureAlgorithms }, | ||
269 | { "bindaddress", oBindAddress }, | 270 | { "bindaddress", oBindAddress }, |
270 | { "bindinterface", oBindInterface }, | 271 | { "bindinterface", oBindInterface }, |
271 | { "clearallforwardings", oClearAllForwardings }, | 272 | { "clearallforwardings", oClearAllForwardings }, |
@@ -1221,6 +1222,10 @@ parse_keytypes: | |||
1221 | *charptr = xstrdup(arg); | 1222 | *charptr = xstrdup(arg); |
1222 | break; | 1223 | break; |
1223 | 1224 | ||
1225 | case oCASignatureAlgorithms: | ||
1226 | charptr = &options->ca_sign_algorithms; | ||
1227 | goto parse_keytypes; | ||
1228 | |||
1224 | case oLogLevel: | 1229 | case oLogLevel: |
1225 | log_level_ptr = &options->log_level; | 1230 | log_level_ptr = &options->log_level; |
1226 | arg = strdelim(&s); | 1231 | arg = strdelim(&s); |
@@ -1836,6 +1841,7 @@ initialize_options(Options * options) | |||
1836 | options->macs = NULL; | 1841 | options->macs = NULL; |
1837 | options->kex_algorithms = NULL; | 1842 | options->kex_algorithms = NULL; |
1838 | options->hostkeyalgorithms = NULL; | 1843 | options->hostkeyalgorithms = NULL; |
1844 | options->ca_sign_algorithms = NULL; | ||
1839 | options->num_identity_files = 0; | 1845 | options->num_identity_files = 0; |
1840 | options->num_certificate_files = 0; | 1846 | options->num_certificate_files = 0; |
1841 | options->hostname = NULL; | 1847 | options->hostname = NULL; |
@@ -1924,7 +1930,7 @@ fill_default_options_for_canonicalization(Options *options) | |||
1924 | void | 1930 | void |
1925 | fill_default_options(Options * options) | 1931 | fill_default_options(Options * options) |
1926 | { | 1932 | { |
1927 | char *all_cipher, *all_mac, *all_kex, *all_key; | 1933 | char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig; |
1928 | int r; | 1934 | int r; |
1929 | 1935 | ||
1930 | if (options->forward_agent == -1) | 1936 | if (options->forward_agent == -1) |
@@ -2077,6 +2083,7 @@ fill_default_options(Options * options) | |||
2077 | all_mac = mac_alg_list(','); | 2083 | all_mac = mac_alg_list(','); |
2078 | all_kex = kex_alg_list(','); | 2084 | all_kex = kex_alg_list(','); |
2079 | all_key = sshkey_alg_list(0, 0, 1, ','); | 2085 | all_key = sshkey_alg_list(0, 0, 1, ','); |
2086 | all_sig = sshkey_alg_list(0, 1, 1, ','); | ||
2080 | #define ASSEMBLE(what, defaults, all) \ | 2087 | #define ASSEMBLE(what, defaults, all) \ |
2081 | do { \ | 2088 | do { \ |
2082 | if ((r = kex_assemble_names(&options->what, \ | 2089 | if ((r = kex_assemble_names(&options->what, \ |
@@ -2088,11 +2095,13 @@ fill_default_options(Options * options) | |||
2088 | ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex); | 2095 | ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex); |
2089 | ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key); | 2096 | ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key); |
2090 | ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key); | 2097 | ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key); |
2098 | ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig); | ||
2091 | #undef ASSEMBLE | 2099 | #undef ASSEMBLE |
2092 | free(all_cipher); | 2100 | free(all_cipher); |
2093 | free(all_mac); | 2101 | free(all_mac); |
2094 | free(all_kex); | 2102 | free(all_kex); |
2095 | free(all_key); | 2103 | free(all_key); |
2104 | free(all_sig); | ||
2096 | 2105 | ||
2097 | #define CLEAR_ON_NONE(v) \ | 2106 | #define CLEAR_ON_NONE(v) \ |
2098 | do { \ | 2107 | do { \ |
@@ -2614,6 +2623,7 @@ dump_client_config(Options *o, const char *host) | |||
2614 | dump_cfg_string(oIgnoreUnknown, o->ignored_unknown); | 2623 | dump_cfg_string(oIgnoreUnknown, o->ignored_unknown); |
2615 | dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); | 2624 | dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); |
2616 | dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX); | 2625 | dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX); |
2626 | dump_cfg_string(oCASignatureAlgorithms, o->ca_sign_algorithms ? o->ca_sign_algorithms : SSH_ALLOWED_CA_SIGALGS); | ||
2617 | dump_cfg_string(oLocalCommand, o->local_command); | 2627 | dump_cfg_string(oLocalCommand, o->local_command); |
2618 | dump_cfg_string(oRemoteCommand, o->remote_command); | 2628 | dump_cfg_string(oRemoteCommand, o->remote_command); |
2619 | dump_cfg_string(oLogLevel, log_level_name(o->log_level)); | 2629 | dump_cfg_string(oLogLevel, log_level_name(o->log_level)); |
diff --git a/readconf.h b/readconf.h index c56887816..fc7e38251 100644 --- a/readconf.h +++ b/readconf.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.h,v 1.127 2018/07/19 10:28:47 dtucker Exp $ */ | 1 | /* $OpenBSD: readconf.h,v 1.128 2018/09/20 03:30:44 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -67,6 +67,7 @@ typedef struct { | |||
67 | char *macs; /* SSH2 macs in order of preference. */ | 67 | char *macs; /* SSH2 macs in order of preference. */ |
68 | char *hostkeyalgorithms; /* SSH2 server key types in order of preference. */ | 68 | char *hostkeyalgorithms; /* SSH2 server key types in order of preference. */ |
69 | char *kex_algorithms; /* SSH2 kex methods in order of preference. */ | 69 | char *kex_algorithms; /* SSH2 kex methods in order of preference. */ |
70 | char *ca_sign_algorithms; /* Allowed CA signature algorithms */ | ||
70 | char *hostname; /* Real host to connect. */ | 71 | char *hostname; /* Real host to connect. */ |
71 | char *host_key_alias; /* hostname alias for .ssh/known_hosts */ | 72 | char *host_key_alias; /* hostname alias for .ssh/known_hosts */ |
72 | char *proxy_command; /* Proxy command for connecting the host. */ | 73 | char *proxy_command; /* Proxy command for connecting the host. */ |
diff --git a/ssh_config.5 b/ssh_config.5 index f499396a3..a9b44cc44 100644 --- a/ssh_config.5 +++ b/ssh_config.5 | |||
@@ -33,8 +33,8 @@ | |||
33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
35 | .\" | 35 | .\" |
36 | .\" $OpenBSD: ssh_config.5,v 1.281 2018/07/23 19:02:49 kn Exp $ | 36 | .\" $OpenBSD: ssh_config.5,v 1.282 2018/09/20 03:30:44 djm Exp $ |
37 | .Dd $Mdocdate: July 23 2018 $ | 37 | .Dd $Mdocdate: September 20 2018 $ |
38 | .Dt SSH_CONFIG 5 | 38 | .Dt SSH_CONFIG 5 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -261,6 +261,18 @@ Only useful on systems with more than one address. | |||
261 | .It Cm BindInterface | 261 | .It Cm BindInterface |
262 | Use the address of the specified interface on the local machine as the | 262 | Use the address of the specified interface on the local machine as the |
263 | source address of the connection. | 263 | source address of the connection. |
264 | .It Cm CASignatureAlgorithms | ||
265 | Specifies which algorithms are allowed for signing of certificates | ||
266 | by certificate authorities (CAs). | ||
267 | The default is: | ||
268 | .Bd -literal -offset indent | ||
269 | ecdsa-sha2-nistp256.ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, | ||
270 | ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa | ||
271 | .Ed | ||
272 | .Pp | ||
273 | .Xr ssh 1 | ||
274 | will not accept host certificates signed using algorithms other than those | ||
275 | specified. | ||
264 | .It Cm CanonicalDomains | 276 | .It Cm CanonicalDomains |
265 | When | 277 | When |
266 | .Cm CanonicalizeHostname | 278 | .Cm CanonicalizeHostname |
diff --git a/sshconnect.c b/sshconnect.c index 78813c164..6d819279e 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect.c,v 1.304 2018/07/27 05:34:42 dtucker Exp $ */ | 1 | /* $OpenBSD: sshconnect.c,v 1.305 2018/09/20 03:30:44 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 |
@@ -734,19 +734,28 @@ confirm(const char *prompt) | |||
734 | } | 734 | } |
735 | 735 | ||
736 | static int | 736 | static int |
737 | check_host_cert(const char *host, const struct sshkey *host_key) | 737 | check_host_cert(const char *host, const struct sshkey *key) |
738 | { | 738 | { |
739 | const char *reason; | 739 | const char *reason; |
740 | int r; | ||
740 | 741 | ||
741 | if (sshkey_cert_check_authority(host_key, 1, 0, host, &reason) != 0) { | 742 | if (sshkey_cert_check_authority(key, 1, 0, host, &reason) != 0) { |
742 | error("%s", reason); | 743 | error("%s", reason); |
743 | return 0; | 744 | return 0; |
744 | } | 745 | } |
745 | if (sshbuf_len(host_key->cert->critical) != 0) { | 746 | if (sshbuf_len(key->cert->critical) != 0) { |
746 | error("Certificate for %s contains unsupported " | 747 | error("Certificate for %s contains unsupported " |
747 | "critical options(s)", host); | 748 | "critical options(s)", host); |
748 | return 0; | 749 | return 0; |
749 | } | 750 | } |
751 | if ((r = sshkey_check_cert_sigtype(key, | ||
752 | options.ca_sign_algorithms)) != 0) { | ||
753 | logit("%s: certificate signature algorithm %s: %s", __func__, | ||
754 | (key->cert == NULL || key->cert->signature_type == NULL) ? | ||
755 | "(null)" : key->cert->signature_type, ssh_err(r)); | ||
756 | return 0; | ||
757 | } | ||
758 | |||
750 | return 1; | 759 | return 1; |
751 | } | 760 | } |
752 | 761 | ||