]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
upstream: sk-usbhid: skip unsupported key types in read_rks()
authordjm@openbsd.org <djm@openbsd.org>
Mon, 1 Jun 2026 05:49:20 +0000 (05:49 +0000)
committerDamien Miller <djm@mindrot.org>
Mon, 1 Jun 2026 05:50:05 +0000 (15:50 +1000)
When enumerating resident keys, encountering a credential with an
unsupported COSE key type (not ES256 or EdDSA) caused the entire
enumeration to abort via goto out, discarding all valid keys.

Move the key type check before the per-credential allocation so
unsupported types can be skipped with continue instead. This
preserves all valid resident keys on the token.

Patch from Akhilesh Arora via GHPR657

OpenBSD-Commit-ID: b344a44ff97d26faf099b8e0cad72ad1e793ac0f

sk-usbhid.c

index cd248811a51ce8449bbefc9a0073d8fc3445d1ab..ce59c4e9317d19de415418d289208996e48f229a 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sk-usbhid.c,v 1.48 2025/05/12 05:41:20 tb Exp $ */
+/* $OpenBSD: sk-usbhid.c,v 1.49 2026/06/01 05:49:20 djm Exp $ */
 /*
  * Copyright (c) 2019 Markus Friedl
  * Copyright (c) 2020 Pedro Martelletto
@@ -1262,6 +1262,7 @@ read_rks(struct sk_usbhid *sk, const char *pin,
     struct sk_resident_key ***rksp, size_t *nrksp)
 {
        int ret = SSH_SK_ERR_GENERAL, r = -1, internal_uv;
+       uint32_t alg;
        fido_credman_metadata_t *metadata = NULL;
        fido_credman_rp_t *rp = NULL;
        fido_credman_rk_t *rk = NULL;
@@ -1358,6 +1359,20 @@ read_rks(struct sk_usbhid *sk, const char *pin,
                            user_id_len, j, fido_cred_type(cred),
                            fido_cred_flags(cred), fido_cred_prot(cred));
 
+                       /* Determine key algorithm */
+                       switch (fido_cred_type(cred)) {
+                       case COSE_ES256:
+                               alg = SSH_SK_ECDSA;
+                               break;
+                       case COSE_EDDSA:
+                               alg = SSH_SK_ED25519;
+                               break;
+                       default:
+                               skdebug(__func__, "unsupported key type %d",
+                                   fido_cred_type(cred));
+                               continue;
+                       }
+
                        /* build response entry */
                        if ((srk = calloc(1, sizeof(*srk))) == NULL ||
                            (srk->key.key_handle = calloc(1,
@@ -1369,6 +1384,7 @@ read_rks(struct sk_usbhid *sk, const char *pin,
                                goto out;
                        }
 
+                       srk->alg = alg;
                        srk->key.key_handle_len = fido_cred_id_len(cred);
                        memcpy(srk->key.key_handle, fido_cred_id_ptr(cred),
                            srk->key.key_handle_len);
@@ -1376,19 +1392,6 @@ read_rks(struct sk_usbhid *sk, const char *pin,
                        if (srk->user_id_len != 0)
                                memcpy(srk->user_id, user_id, srk->user_id_len);
 
-                       switch (fido_cred_type(cred)) {
-                       case COSE_ES256:
-                               srk->alg = SSH_SK_ECDSA;
-                               break;
-                       case COSE_EDDSA:
-                               srk->alg = SSH_SK_ED25519;
-                               break;
-                       default:
-                               skdebug(__func__, "unsupported key type %d",
-                                   fido_cred_type(cred));
-                               goto out; /* XXX free rk and continue */
-                       }
-
                        if (fido_cred_prot(cred) == FIDO_CRED_PROT_UV_REQUIRED
                            && internal_uv == -1)
                                srk->flags |=  SSH_SK_USER_VERIFICATION_REQD;