be more strict in parsing key type names. Only allow shortnames (e.g
authordjm <djm@openbsd.org>
Wed, 4 Sep 2024 05:33:34 +0000 (05:33 +0000)
committerdjm <djm@openbsd.org>
Wed, 4 Sep 2024 05:33:34 +0000 (05:33 +0000)
"rsa") in user-interface code and require full SSH protocol names (e.g.
"ssh-rsa") everywhere else.

Prompted by bz3725; ok markus@

usr.bin/ssh/ssh-keygen.c
usr.bin/ssh/ssh-keyscan.c
usr.bin/ssh/sshkey.c
usr.bin/ssh/sshkey.h

index 4a95c55..71ad9a3 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keygen.c,v 1.473 2024/08/15 00:51:51 djm Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.474 2024/09/04 05:33:34 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -250,7 +250,7 @@ ask_filename(struct passwd *pw, const char *prompt)
        if (key_type_name == NULL)
                name = _PATH_SSH_CLIENT_ID_ED25519;
        else {
-               switch (sshkey_type_from_name(key_type_name)) {
+               switch (sshkey_type_from_shortname(key_type_name)) {
 #ifdef WITH_DSA
                case KEY_DSA_CERT:
                case KEY_DSA:
@@ -1117,7 +1117,7 @@ do_gen_all_hostkeys(struct passwd *pw)
                }
                printf("%s ", key_types[i].key_type_display);
                fflush(stdout);
-               type = sshkey_type_from_name(key_types[i].key_type);
+               type = sshkey_type_from_shortname(key_types[i].key_type);
                if ((fd = mkstemp(prv_tmp)) == -1) {
                        error("Could not save your private key in %s: %s",
                            prv_tmp, strerror(errno));
@@ -1823,7 +1823,7 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
        free(tmp);
 
        if (key_type_name != NULL) {
-               if (sshkey_type_from_name(key_type_name) != ca->type) {
+               if (sshkey_type_from_shortname(key_type_name) != ca->type) {
                        fatal("CA key type %s doesn't match specified %s",
                            sshkey_ssh_name(ca), key_type_name);
                }
@@ -3810,7 +3810,7 @@ main(int argc, char **argv)
        if (key_type_name == NULL)
                key_type_name = DEFAULT_KEY_TYPE_NAME;
 
-       type = sshkey_type_from_name(key_type_name);
+       type = sshkey_type_from_shortname(key_type_name);
        type_bits_valid(type, key_type_name, &bits);
 
        if (!quiet)
index e941c21..a204391 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keyscan.c,v 1.159 2024/09/02 12:13:56 djm Exp $ */
+/* $OpenBSD: ssh-keyscan.c,v 1.160 2024/09/04 05:33:34 djm Exp $ */
 /*
  * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
  *
@@ -726,7 +726,7 @@ main(int argc, char **argv)
                        get_keytypes = 0;
                        tname = strtok(optarg, ",");
                        while (tname) {
-                               int type = sshkey_type_from_name(tname);
+                               int type = sshkey_type_from_shortname(tname);
 
                                switch (type) {
 #ifdef WITH_DSA
index d04cc52..1ebcd1c 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.c,v 1.145 2024/08/20 11:10:04 djm Exp $ */
+/* $OpenBSD: sshkey.c,v 1.146 2024/09/04 05:33:34 djm Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2008 Alexander von Gernler.  All rights reserved.
@@ -228,22 +228,36 @@ sshkey_ssh_name_plain(const struct sshkey *k)
            k->ecdsa_nid);
 }
 
-int
-sshkey_type_from_name(const char *name)
+static int
+type_from_name(const char *name, int allow_short)
 {
        int i;
        const struct sshkey_impl *impl;
 
        for (i = 0; keyimpls[i] != NULL; i++) {
                impl = keyimpls[i];
+               if (impl->name != NULL && strcmp(name, impl->name) == 0)
+                       return impl->type;
                /* Only allow shortname matches for plain key types */
-               if ((impl->name != NULL && strcmp(name, impl->name) == 0) ||
-                   (!impl->cert && strcasecmp(impl->shortname, name) == 0))
+               if (allow_short && !impl->cert && impl->shortname != NULL &&
+                   strcasecmp(impl->shortname, name) == 0)
                        return impl->type;
        }
        return KEY_UNSPEC;
 }
 
+int
+sshkey_type_from_name(const char *name)
+{
+       return type_from_name(name, 0);
+}
+
+int
+sshkey_type_from_shortname(const char *name)
+{
+       return type_from_name(name, 1);
+}
+
 static int
 key_type_is_ecdsa_variant(int type)
 {
index 21298c6..eddd23b 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.h,v 1.64 2024/08/15 00:51:51 djm Exp $ */
+/* $OpenBSD: sshkey.h,v 1.65 2024/09/04 05:33:34 djm Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -218,6 +218,7 @@ int          sshkey_shield_private(struct sshkey *);
 int             sshkey_unshield_private(struct sshkey *);
 
 int     sshkey_type_from_name(const char *);
+int     sshkey_type_from_shortname(const char *);
 int     sshkey_is_cert(const struct sshkey *);
 int     sshkey_is_sk(const struct sshkey *);
 int     sshkey_type_is_cert(int);