-/* $OpenBSD: readconf.c,v 1.368 2022/06/03 04:30:47 djm Exp $ */
+/* $OpenBSD: readconf.c,v 1.369 2022/09/17 10:33:18 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
oFingerprintHash, oUpdateHostkeys, oHostbasedAcceptedAlgorithms,
oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump,
- oSecurityKeyProvider, oKnownHostsCommand,
+ oSecurityKeyProvider, oKnownHostsCommand, oRequiredRSASize,
oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
} OpCodes;
{ "proxyjump", oProxyJump },
{ "securitykeyprovider", oSecurityKeyProvider },
{ "knownhostscommand", oKnownHostsCommand },
+ { "requiredrsasize", oRequiredRSASize },
{ NULL, oBadOption }
};
*charptr = xstrdup(arg);
break;
+ case oRequiredRSASize:
+ intptr = &options->required_rsa_size;
+ goto parse_int;
+
case oDeprecated:
debug("%s line %d: Deprecated option \"%s\"",
filename, linenum, keyword);
options->hostbased_accepted_algos = NULL;
options->pubkey_accepted_algos = NULL;
options->known_hosts_command = NULL;
+ options->required_rsa_size = -1;
}
/*
options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
if (options->sk_provider == NULL)
options->sk_provider = xstrdup("internal");
+ if (options->required_rsa_size == -1)
+ options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
/* Expand KEX name lists */
all_cipher = cipher_alg_list(',', 0);
dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
+ dump_cfg_int(oRequiredRSASize, o->required_rsa_size);
/* String options */
dump_cfg_string(oBindAddress, o->bind_address);
-/* $OpenBSD: readconf.h,v 1.147 2022/06/03 04:30:47 djm Exp $ */
+/* $OpenBSD: readconf.h,v 1.148 2022/09/17 10:33:18 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
char *known_hosts_command;
+ int required_rsa_size; /* minimum size of RSA keys */
+
char *ignored_unknown; /* Pattern list of unknown tokens to ignore */
} Options;
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $OpenBSD: ssh.1,v 1.431 2022/05/28 05:57:56 jmc Exp $
-.Dd $Mdocdate: May 28 2022 $
+.\" $OpenBSD: ssh.1,v 1.432 2022/09/17 10:33:18 djm Exp $
+.Dd $Mdocdate: September 17 2022 $
.Dt SSH 1
.Os
.Sh NAME
.It RemoteCommand
.It RemoteForward
.It RequestTTY
+.It RequiredRSASize
.It SendEnv
.It ServerAliveInterval
.It ServerAliveCountMax
-/* $OpenBSD: ssh.c,v 1.575 2022/07/01 00:36:30 djm Exp $ */
+/* $OpenBSD: ssh.c,v 1.576 2022/09/17 10:33:18 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
}
/*
- * Check the result of hostkey loading, ignoring some errors and
- * fatal()ing for others.
+ * Check the result of hostkey loading, ignoring some errors and either
+ * discarding the key or fatal()ing for others.
*/
static void
-check_load(int r, const char *path, const char *message)
+check_load(int r, struct sshkey **k, const char *path, const char *message)
{
switch (r) {
case 0:
+ /* Check RSA keys size and discard if undersized */
+ if (k != NULL && *k != NULL &&
+ (r = sshkey_check_rsa_length(*k,
+ options.required_rsa_size)) != 0) {
+ error_r(r, "load %s \"%s\"", message, path);
+ free(*k);
+ *k = NULL;
+ }
break;
case SSH_ERR_INTERNAL_ERROR:
case SSH_ERR_ALLOC_FAIL:
if ((o) >= sensitive_data.nkeys) \
fatal_f("pubkey out of array bounds"); \
check_load(sshkey_load_public(p, &(sensitive_data.keys[o]), NULL), \
- p, "pubkey"); \
+ &(sensitive_data.keys[o]), p, "pubkey"); \
if (sensitive_data.keys[o] != NULL) \
debug2("hostbased key %d: %s key from \"%s\"", o, \
sshkey_ssh_name(sensitive_data.keys[o]), p); \
#define L_CERT(p,o) do { \
if ((o) >= sensitive_data.nkeys) \
fatal_f("cert out of array bounds"); \
- check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), p, "cert"); \
+ check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), \
+ &(sensitive_data.keys[o]), p, "cert"); \
if (sensitive_data.keys[o] != NULL) \
debug2("hostbased key %d: %s cert from \"%s\"", o, \
sshkey_ssh_name(sensitive_data.keys[o]), p); \
filename = default_client_percent_dollar_expand(cp, cinfo);
free(cp);
check_load(sshkey_load_public(filename, &public, NULL),
- filename, "pubkey");
+ &public, filename, "pubkey");
debug("identity file %s type %d", filename,
public ? public->type : -1);
free(options.identity_files[i]);
continue;
xasprintf(&cp, "%s-cert", filename);
check_load(sshkey_load_public(cp, &public, NULL),
- filename, "pubkey");
+ &public, filename, "pubkey");
debug("identity file %s type %d", cp,
public ? public->type : -1);
if (public == NULL) {
free(cp);
check_load(sshkey_load_public(filename, &public, NULL),
- filename, "certificate");
+ &public, filename, "certificate");
debug("certificate file %s type %d", filename,
public ? public->type : -1);
free(options.certificate_files[i]);
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $OpenBSD: ssh_config.5,v 1.373 2022/06/24 04:27:14 djm Exp $
-.Dd $Mdocdate: June 24 2022 $
+.\" $OpenBSD: ssh_config.5,v 1.374 2022/09/17 10:33:18 djm Exp $
+.Dd $Mdocdate: September 17 2022 $
.Dt SSH_CONFIG 5
.Os
.Sh NAME
.Fl T
flags for
.Xr ssh 1 .
+.It Cm RequiredRSASize
+Specifies the minimum RSA key size (in bits) that
+.Xr ssh 1
+will accept.
+User authentication keys smaller than this limit will be ignored.
+Servers that present host keys smaller than this limit will cause the
+connection to be terminated.
+The default is
+.Cm 1024
+bits.
+Note that this limit may only be raised from the default.
.It Cm RevokedHostKeys
Specifies revoked host public keys.
Keys listed in this file will be refused for host authentication.
-/* $OpenBSD: sshconnect2.c,v 1.360 2022/08/19 06:07:47 djm Exp $ */
+/* $OpenBSD: sshconnect2.c,v 1.361 2022/09/17 10:33:18 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Damien Miller. All rights reserved.
static int
verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh)
{
+ int r;
+
+ if ((r = sshkey_check_rsa_length(hostkey,
+ options.required_rsa_size)) != 0)
+ fatal_r(r, "Bad server host key");
if (verify_host_key(xxx_host, xxx_hostaddr, hostkey,
xxx_conn_info) == -1)
fatal("Host key verification failed.");
private = NULL;
quit = 1;
}
+ if (!quit && (r = sshkey_check_rsa_length(private,
+ options.required_rsa_size)) != 0) {
+ debug_fr(r, "Skipping key %s", id->filename);
+ sshkey_free(private);
+ private = NULL;
+ quit = 1;
+ }
if (!quit && private != NULL && id->agent_fd == -1 &&
!(id->key && id->isprivate))
maybe_add_key_to_agent(id->filename, private, comment,
/* list of keys supported by the agent */
if ((r = get_agent_identities(ssh, &agent_fd, &idlist)) == 0) {
for (j = 0; j < idlist->nkeys; j++) {
+ if ((r = sshkey_check_rsa_length(idlist->keys[j],
+ options.required_rsa_size)) != 0) {
+ debug_fr(r, "ignoring %s agent key",
+ sshkey_ssh_name(idlist->keys[j]));
+ continue;
+ }
found = 0;
TAILQ_FOREACH(id, &files, next) {
/*