From a73db88df08a74e797ff99b17a2e585f91e6be23 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Fri, 30 Oct 2026 04:48:41 +0000 Subject: [PATCH] upstream: avoid fatal() if a PKCS#11 key was added multiple times (e.g. for multiple certificates) and then subsequently freed. The key-free code incorrectly assumed that keys were singular. Anthropic ANT-2026-V7H1QCC4 OpenBSD-Commit-ID: 9a5575d6733d91666dc86de841601d17b483df9f --- ssh-pkcs11-client.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c index b6d158bb4..7ab5e5a1b 100644 --- a/ssh-pkcs11-client.c +++ b/ssh-pkcs11-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11-client.c,v 1.27 2026/10/30 01:41:01 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11-client.c,v 1.28 2026/10/30 04:48:41 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * Copyright (c) 2014 Pedro Martelletto. All rights reserved. @@ -480,15 +480,20 @@ pkcs11_key_free(struct sshkey *key) if ((r = sshkey_putb(key, keyblob)) != 0) fatal_fr(r, "serialise key"); - /* repack keys */ + /* + * Remove one record of the key and repack. A key may legitimately be + * recorded more than once, e.g. when pkcs11_make_cert() is called + * repeatedly for the same certificate, so remove the first match only + * and leave any others for the remaining sshkey instances. + */ for (i = 0; i < helper->nkeyblobs; i++) { - if (sshbuf_equals(keyblob, helper->keyblobs[i]) == 0) { - if (found) - fatal_f("key recorded more than once"); + if (!found && sshbuf_equals(keyblob, helper->keyblobs[i]) == 0) { + sshbuf_free(helper->keyblobs[i]); found = 1; } else if (found) helper->keyblobs[i - 1] = helper->keyblobs[i]; } + sshbuf_free(keyblob); if (found) { helper->keyblobs = xrecallocarray(helper->keyblobs, helper->nkeyblobs, helper->nkeyblobs - 1,