summaryrefslogtreecommitdiffstats
path: root/meta/recipes-connectivity/openssh/openssh/CVE-2023-38408-02.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-connectivity/openssh/openssh/CVE-2023-38408-02.patch')
-rw-r--r--meta/recipes-connectivity/openssh/openssh/CVE-2023-38408-02.patch581
1 files changed, 581 insertions, 0 deletions
diff --git a/meta/recipes-connectivity/openssh/openssh/CVE-2023-38408-02.patch b/meta/recipes-connectivity/openssh/openssh/CVE-2023-38408-02.patch
new file mode 100644
index 0000000000..25ba921869
--- /dev/null
+++ b/meta/recipes-connectivity/openssh/openssh/CVE-2023-38408-02.patch
@@ -0,0 +1,581 @@
1From 92cebfbcc221c9ef3f6bbb78da3d7699c0ae56be Mon Sep 17 00:00:00 2001
2From: "djm@openbsd.org" <djm@openbsd.org>
3Date: Wed, 19 Jul 2023 14:03:45 +0000
4Subject: [PATCH 02/12] upstream: Separate ssh-pkcs11-helpers for each p11
5 module
6
7Make ssh-pkcs11-client start an independent helper for each provider,
8providing better isolation between modules and reliability if a single
9module misbehaves.
10
11This also implements reference counting of PKCS#11-hosted keys,
12allowing ssh-pkcs11-helper subprocesses to be automatically reaped
13when no remaining keys reference them. This fixes some bugs we have
14that make PKCS11 keys unusable after they have been deleted, e.g.
15https://bugzilla.mindrot.org/show_bug.cgi?id=3125
16
17ok markus@
18
19OpenBSD-Commit-ID: 0ce188b14fe271ab0568f4500070d96c5657244e
20
21Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/099cdf59ce1e72f55d421c8445bf6321b3004755]
22CVE: CVE-2023-38408
23Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
24---
25 ssh-pkcs11-client.c | 372 +++++++++++++++++++++++++++++++++-----------
26 1 file changed, 282 insertions(+), 90 deletions(-)
27
28diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c
29index 41114c7..4f3c6ed 100644
30--- a/ssh-pkcs11-client.c
31+++ b/ssh-pkcs11-client.c
32@@ -1,4 +1,4 @@
33-/* $OpenBSD: ssh-pkcs11-client.c,v 1.16 2020/01/25 00:03:36 djm Exp $ */
34+/* $OpenBSD: ssh-pkcs11-client.c,v 1.18 2023/07/19 14:03:45 djm Exp $ */
35 /*
36 * Copyright (c) 2010 Markus Friedl. All rights reserved.
37 * Copyright (c) 2014 Pedro Martelletto. All rights reserved.
38@@ -30,12 +30,11 @@
39 #include <string.h>
40 #include <unistd.h>
41 #include <errno.h>
42+#include <limits.h>
43
44 #include <openssl/ecdsa.h>
45 #include <openssl/rsa.h>
46
47-#include "openbsd-compat/openssl-compat.h"
48-
49 #include "pathnames.h"
50 #include "xmalloc.h"
51 #include "sshbuf.h"
52@@ -47,18 +46,140 @@
53 #include "ssh-pkcs11.h"
54 #include "ssherr.h"
55
56+#include "openbsd-compat/openssl-compat.h"
57+
58 /* borrows code from sftp-server and ssh-agent */
59
60-static int fd = -1;
61-static pid_t pid = -1;
62+/*
63+ * Maintain a list of ssh-pkcs11-helper subprocesses. These may be looked up
64+ * by provider path or their unique EC/RSA METHOD pointers.
65+ */
66+struct helper {
67+ char *path;
68+ pid_t pid;
69+ int fd;
70+ RSA_METHOD *rsa_meth;
71+ EC_KEY_METHOD *ec_meth;
72+ int (*rsa_finish)(RSA *rsa);
73+ void (*ec_finish)(EC_KEY *key);
74+ size_t nrsa, nec; /* number of active keys of each type */
75+};
76+static struct helper **helpers;
77+static size_t nhelpers;
78+
79+static struct helper *
80+helper_by_provider(const char *path)
81+{
82+ size_t i;
83+
84+ for (i = 0; i < nhelpers; i++) {
85+ if (helpers[i] == NULL || helpers[i]->path == NULL ||
86+ helpers[i]->fd == -1)
87+ continue;
88+ if (strcmp(helpers[i]->path, path) == 0)
89+ return helpers[i];
90+ }
91+ return NULL;
92+}
93+
94+static struct helper *
95+helper_by_rsa(const RSA *rsa)
96+{
97+ size_t i;
98+ const RSA_METHOD *meth;
99+
100+ if ((meth = RSA_get_method(rsa)) == NULL)
101+ return NULL;
102+ for (i = 0; i < nhelpers; i++) {
103+ if (helpers[i] != NULL && helpers[i]->rsa_meth == meth)
104+ return helpers[i];
105+ }
106+ return NULL;
107+
108+}
109+
110+static struct helper *
111+helper_by_ec(const EC_KEY *ec)
112+{
113+ size_t i;
114+ const EC_KEY_METHOD *meth;
115+
116+ if ((meth = EC_KEY_get_method(ec)) == NULL)
117+ return NULL;
118+ for (i = 0; i < nhelpers; i++) {
119+ if (helpers[i] != NULL && helpers[i]->ec_meth == meth)
120+ return helpers[i];
121+ }
122+ return NULL;
123+
124+}
125+
126+static void
127+helper_free(struct helper *helper)
128+{
129+ size_t i;
130+ int found = 0;
131+
132+ if (helper == NULL)
133+ return;
134+ if (helper->path == NULL || helper->ec_meth == NULL ||
135+ helper->rsa_meth == NULL)
136+ fatal("%s: inconsistent helper", __func__);
137+ debug3("%s: free helper for provider %s", __func__ , helper->path);
138+ for (i = 0; i < nhelpers; i++) {
139+ if (helpers[i] == helper) {
140+ if (found)
141+ fatal("%s: helper recorded more than once", __func__);
142+ found = 1;
143+ }
144+ else if (found)
145+ helpers[i - 1] = helpers[i];
146+ }
147+ if (found) {
148+ helpers = xrecallocarray(helpers, nhelpers,
149+ nhelpers - 1, sizeof(*helpers));
150+ nhelpers--;
151+ }
152+ free(helper->path);
153+ EC_KEY_METHOD_free(helper->ec_meth);
154+ RSA_meth_free(helper->rsa_meth);
155+ free(helper);
156+}
157+
158+static void
159+helper_terminate(struct helper *helper)
160+{
161+ if (helper == NULL) {
162+ return;
163+ } else if (helper->fd == -1) {
164+ debug3("%s: already terminated", __func__);
165+ } else {
166+ debug3("terminating helper for %s; "
167+ "remaining %zu RSA %zu ECDSA", __func__,
168+ helper->path, helper->nrsa, helper->nec);
169+ close(helper->fd);
170+ /* XXX waitpid() */
171+ helper->fd = -1;
172+ helper->pid = -1;
173+ }
174+ /*
175+ * Don't delete the helper entry until there are no remaining keys
176+ * that reference it. Otherwise, any signing operation would call
177+ * a free'd METHOD pointer and that would be bad.
178+ */
179+ if (helper->nrsa == 0 && helper->nec == 0)
180+ helper_free(helper);
181+}
182
183 static void
184-send_msg(struct sshbuf *m)
185+send_msg(int fd, struct sshbuf *m)
186 {
187 u_char buf[4];
188 size_t mlen = sshbuf_len(m);
189 int r;
190
191+ if (fd == -1)
192+ return;
193 POKE_U32(buf, mlen);
194 if (atomicio(vwrite, fd, buf, 4) != 4 ||
195 atomicio(vwrite, fd, sshbuf_mutable_ptr(m),
196@@ -69,12 +190,15 @@ send_msg(struct sshbuf *m)
197 }
198
199 static int
200-recv_msg(struct sshbuf *m)
201+recv_msg(int fd, struct sshbuf *m)
202 {
203 u_int l, len;
204 u_char c, buf[1024];
205 int r;
206
207+ sshbuf_reset(m);
208+ if (fd == -1)
209+ return 0; /* XXX */
210 if ((len = atomicio(read, fd, buf, 4)) != 4) {
211 error("read from helper failed: %u", len);
212 return (0); /* XXX */
213@@ -83,7 +207,6 @@ recv_msg(struct sshbuf *m)
214 if (len > 256 * 1024)
215 fatal("response too long: %u", len);
216 /* read len bytes into m */
217- sshbuf_reset(m);
218 while (len > 0) {
219 l = len;
220 if (l > sizeof(buf))
221@@ -104,14 +227,17 @@ recv_msg(struct sshbuf *m)
222 int
223 pkcs11_init(int interactive)
224 {
225- return (0);
226+ return 0;
227 }
228
229 void
230 pkcs11_terminate(void)
231 {
232- if (fd >= 0)
233- close(fd);
234+ size_t i;
235+
236+ debug3("%s: terminating %zu helpers", __func__, nhelpers);
237+ for (i = 0; i < nhelpers; i++)
238+ helper_terminate(helpers[i]);
239 }
240
241 static int
242@@ -122,7 +248,11 @@ rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding)
243 u_char *blob = NULL, *signature = NULL;
244 size_t blen, slen = 0;
245 int r, ret = -1;
246+ struct helper *helper;
247
248+ if ((helper = helper_by_rsa(rsa)) == NULL || helper->fd == -1)
249+ fatal("%s: no helper for PKCS11 key", __func__);
250+ debug3("%s: signing with PKCS11 provider %s", __func__, helper->path);
251 if (padding != RSA_PKCS1_PADDING)
252 goto fail;
253 key = sshkey_new(KEY_UNSPEC);
254@@ -144,10 +274,10 @@ rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding)
255 (r = sshbuf_put_string(msg, from, flen)) != 0 ||
256 (r = sshbuf_put_u32(msg, 0)) != 0)
257 fatal("%s: buffer error: %s", __func__, ssh_err(r));
258- send_msg(msg);
259+ send_msg(helper->fd, msg);
260 sshbuf_reset(msg);
261
262- if (recv_msg(msg) == SSH2_AGENT_SIGN_RESPONSE) {
263+ if (recv_msg(helper->fd, msg) == SSH2_AGENT_SIGN_RESPONSE) {
264 if ((r = sshbuf_get_string(msg, &signature, &slen)) != 0)
265 fatal("%s: buffer error: %s", __func__, ssh_err(r));
266 if (slen <= (size_t)RSA_size(rsa)) {
267@@ -163,7 +293,26 @@ rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding)
268 return (ret);
269 }
270
271-#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW)
272+static int
273+rsa_finish(RSA *rsa)
274+{
275+ struct helper *helper;
276+
277+ if ((helper = helper_by_rsa(rsa)) == NULL)
278+ fatal("%s: no helper for PKCS11 key", __func__);
279+ debug3("%s: free PKCS11 RSA key for provider %s", __func__, helper->path);
280+ if (helper->rsa_finish != NULL)
281+ helper->rsa_finish(rsa);
282+ if (helper->nrsa == 0)
283+ fatal("%s: RSA refcount error", __func__);
284+ helper->nrsa--;
285+ debug3("%s: provider %s remaining keys: %zu RSA %zu ECDSA", __func__,
286+ helper->path, helper->nrsa, helper->nec);
287+ if (helper->nrsa == 0 && helper->nec == 0)
288+ helper_terminate(helper);
289+ return 1;
290+}
291+
292 static ECDSA_SIG *
293 ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
294 const BIGNUM *rp, EC_KEY *ec)
295@@ -175,7 +324,11 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
296 u_char *blob = NULL, *signature = NULL;
297 size_t blen, slen = 0;
298 int r, nid;
299+ struct helper *helper;
300
301+ if ((helper = helper_by_ec(ec)) == NULL || helper->fd == -1)
302+ fatal("%s: no helper for PKCS11 key", __func__);
303+ debug3("%s: signing with PKCS11 provider %s", __func__, helper->path);
304 nid = sshkey_ecdsa_key_to_nid(ec);
305 if (nid < 0) {
306 error("%s: couldn't get curve nid", __func__);
307@@ -203,10 +356,10 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
308 (r = sshbuf_put_string(msg, dgst, dgst_len)) != 0 ||
309 (r = sshbuf_put_u32(msg, 0)) != 0)
310 fatal("%s: buffer error: %s", __func__, ssh_err(r));
311- send_msg(msg);
312+ send_msg(helper->fd, msg);
313 sshbuf_reset(msg);
314
315- if (recv_msg(msg) == SSH2_AGENT_SIGN_RESPONSE) {
316+ if (recv_msg(helper->fd, msg) == SSH2_AGENT_SIGN_RESPONSE) {
317 if ((r = sshbuf_get_string(msg, &signature, &slen)) != 0)
318 fatal("%s: buffer error: %s", __func__, ssh_err(r));
319 cp = signature;
320@@ -220,75 +373,110 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
321 sshbuf_free(msg);
322 return (ret);
323 }
324-#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */
325
326-static RSA_METHOD *helper_rsa;
327-#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW)
328-static EC_KEY_METHOD *helper_ecdsa;
329-#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */
330+static void
331+ecdsa_do_finish(EC_KEY *ec)
332+{
333+ struct helper *helper;
334+
335+ if ((helper = helper_by_ec(ec)) == NULL)
336+ fatal("%s: no helper for PKCS11 key", __func__);
337+ debug3("%s: free PKCS11 ECDSA key for provider %s", __func__, helper->path);
338+ if (helper->ec_finish != NULL)
339+ helper->ec_finish(ec);
340+ if (helper->nec == 0)
341+ fatal("%s: ECDSA refcount error", __func__);
342+ helper->nec--;
343+ debug3("%s: provider %s remaining keys: %zu RSA %zu ECDSA", __func__,
344+ helper->path, helper->nrsa, helper->nec);
345+ if (helper->nrsa == 0 && helper->nec == 0)
346+ helper_terminate(helper);
347+}
348
349 /* redirect private key crypto operations to the ssh-pkcs11-helper */
350 static void
351-wrap_key(struct sshkey *k)
352+wrap_key(struct helper *helper, struct sshkey *k)
353 {
354- if (k->type == KEY_RSA)
355- RSA_set_method(k->rsa, helper_rsa);
356-#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW)
357- else if (k->type == KEY_ECDSA)
358- EC_KEY_set_method(k->ecdsa, helper_ecdsa);
359-#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */
360- else
361+ debug3("%s: wrap %s for provider %s", __func__, sshkey_type(k), helper->path);
362+ if (k->type == KEY_RSA) {
363+ RSA_set_method(k->rsa, helper->rsa_meth);
364+ if (helper->nrsa++ >= INT_MAX)
365+ fatal("%s: RSA refcount error", __func__);
366+ } else if (k->type == KEY_ECDSA) {
367+ EC_KEY_set_method(k->ecdsa, helper->ec_meth);
368+ if (helper->nec++ >= INT_MAX)
369+ fatal("%s: EC refcount error", __func__);
370+ } else
371 fatal("%s: unknown key type", __func__);
372+ k->flags |= SSHKEY_FLAG_EXT;
373+ debug3("%s: provider %s remaining keys: %zu RSA %zu ECDSA", __func__,
374+ helper->path, helper->nrsa, helper->nec);
375 }
376
377 static int
378-pkcs11_start_helper_methods(void)
379+pkcs11_start_helper_methods(struct helper *helper)
380 {
381- if (helper_rsa != NULL)
382- return (0);
383-
384-#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW)
385- int (*orig_sign)(int, const unsigned char *, int, unsigned char *,
386+ int (*ec_init)(EC_KEY *key);
387+ int (*ec_copy)(EC_KEY *dest, const EC_KEY *src);
388+ int (*ec_set_group)(EC_KEY *key, const EC_GROUP *grp);
389+ int (*ec_set_private)(EC_KEY *key, const BIGNUM *priv_key);
390+ int (*ec_set_public)(EC_KEY *key, const EC_POINT *pub_key);
391+ int (*ec_sign)(int, const unsigned char *, int, unsigned char *,
392 unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *) = NULL;
393- if (helper_ecdsa != NULL)
394- return (0);
395- helper_ecdsa = EC_KEY_METHOD_new(EC_KEY_OpenSSL());
396- if (helper_ecdsa == NULL)
397- return (-1);
398- EC_KEY_METHOD_get_sign(helper_ecdsa, &orig_sign, NULL, NULL);
399- EC_KEY_METHOD_set_sign(helper_ecdsa, orig_sign, NULL, ecdsa_do_sign);
400-#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */
401-
402- if ((helper_rsa = RSA_meth_dup(RSA_get_default_method())) == NULL)
403+ RSA_METHOD *rsa_meth;
404+ EC_KEY_METHOD *ec_meth;
405+
406+ if ((ec_meth = EC_KEY_METHOD_new(EC_KEY_OpenSSL())) == NULL)
407+ return -1;
408+ EC_KEY_METHOD_get_sign(ec_meth, &ec_sign, NULL, NULL);
409+ EC_KEY_METHOD_set_sign(ec_meth, ec_sign, NULL, ecdsa_do_sign);
410+ EC_KEY_METHOD_get_init(ec_meth, &ec_init, &helper->ec_finish,
411+ &ec_copy, &ec_set_group, &ec_set_private, &ec_set_public);
412+ EC_KEY_METHOD_set_init(ec_meth, ec_init, ecdsa_do_finish,
413+ ec_copy, ec_set_group, ec_set_private, ec_set_public);
414+
415+ if ((rsa_meth = RSA_meth_dup(RSA_get_default_method())) == NULL)
416 fatal("%s: RSA_meth_dup failed", __func__);
417- if (!RSA_meth_set1_name(helper_rsa, "ssh-pkcs11-helper") ||
418- !RSA_meth_set_priv_enc(helper_rsa, rsa_encrypt))
419+ helper->rsa_finish = RSA_meth_get_finish(rsa_meth);
420+ if (!RSA_meth_set1_name(rsa_meth, "ssh-pkcs11-helper") ||
421+ !RSA_meth_set_priv_enc(rsa_meth, rsa_encrypt) ||
422+ !RSA_meth_set_finish(rsa_meth, rsa_finish))
423 fatal("%s: failed to prepare method", __func__);
424
425- return (0);
426+ helper->ec_meth = ec_meth;
427+ helper->rsa_meth = rsa_meth;
428+ return 0;
429 }
430
431-static int
432-pkcs11_start_helper(void)
433+static struct helper *
434+pkcs11_start_helper(const char *path)
435 {
436 int pair[2];
437- char *helper, *verbosity = NULL;
438-
439- if (log_level_get() >= SYSLOG_LEVEL_DEBUG1)
440- verbosity = "-vvv";
441-
442- if (pkcs11_start_helper_methods() == -1) {
443- error("pkcs11_start_helper_methods failed");
444- return (-1);
445- }
446+ char *prog, *verbosity = NULL;
447+ struct helper *helper;
448+ pid_t pid;
449
450+ if (nhelpers >= INT_MAX)
451+ fatal("%s: too many helpers", __func__);
452+ debug3("%s: start helper for %s", __func__, path);
453 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) {
454 error("socketpair: %s", strerror(errno));
455- return (-1);
456+ return NULL;
457+ }
458+ helper = xcalloc(1, sizeof(*helper));
459+ if (pkcs11_start_helper_methods(helper) == -1) {
460+ error("pkcs11_start_helper_methods failed");
461+ goto fail;
462 }
463 if ((pid = fork()) == -1) {
464 error("fork: %s", strerror(errno));
465- return (-1);
466+ fail:
467+ close(pair[0]);
468+ close(pair[1]);
469+ RSA_meth_free(helper->rsa_meth);
470+ EC_KEY_METHOD_free(helper->ec_meth);
471+ free(helper);
472+ return NULL;
473 } else if (pid == 0) {
474 if ((dup2(pair[1], STDIN_FILENO) == -1) ||
475 (dup2(pair[1], STDOUT_FILENO) == -1)) {
476@@ -297,18 +485,27 @@ pkcs11_start_helper(void)
477 }
478 close(pair[0]);
479 close(pair[1]);
480- helper = getenv("SSH_PKCS11_HELPER");
481- if (helper == NULL || strlen(helper) == 0)
482- helper = _PATH_SSH_PKCS11_HELPER;
483+ prog = getenv("SSH_PKCS11_HELPER");
484+ if (prog == NULL || strlen(prog) == 0)
485+ prog = _PATH_SSH_PKCS11_HELPER;
486+ if (log_level_get() >= SYSLOG_LEVEL_DEBUG1)
487+ verbosity = "-vvv";
488 debug("%s: starting %s %s", __func__, helper,
489 verbosity == NULL ? "" : verbosity);
490- execlp(helper, helper, verbosity, (char *)NULL);
491- fprintf(stderr, "exec: %s: %s\n", helper, strerror(errno));
492+ execlp(prog, prog, verbosity, (char *)NULL);
493+ fprintf(stderr, "exec: %s: %s\n", prog, strerror(errno));
494 _exit(1);
495 }
496 close(pair[1]);
497- fd = pair[0];
498- return (0);
499+ helper->fd = pair[0];
500+ helper->path = xstrdup(path);
501+ helper->pid = pid;
502+ debug3("%s: helper %zu for \"%s\" on fd %d pid %ld", __func__, nhelpers,
503+ helper->path, helper->fd, (long)helper->pid);
504+ helpers = xrecallocarray(helpers, nhelpers,
505+ nhelpers + 1, sizeof(*helpers));
506+ helpers[nhelpers++] = helper;
507+ return helper;
508 }
509
510 int
511@@ -322,9 +519,11 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp,
512 size_t blen;
513 u_int nkeys, i;
514 struct sshbuf *msg;
515+ struct helper *helper;
516
517- if (fd < 0 && pkcs11_start_helper() < 0)
518- return (-1);
519+ if ((helper = helper_by_provider(name)) == NULL &&
520+ (helper = pkcs11_start_helper(name)) == NULL)
521+ return -1;
522
523 if ((msg = sshbuf_new()) == NULL)
524 fatal("%s: sshbuf_new failed", __func__);
525@@ -332,10 +531,10 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp,
526 (r = sshbuf_put_cstring(msg, name)) != 0 ||
527 (r = sshbuf_put_cstring(msg, pin)) != 0)
528 fatal("%s: buffer error: %s", __func__, ssh_err(r));
529- send_msg(msg);
530+ send_msg(helper->fd, msg);
531 sshbuf_reset(msg);
532
533- type = recv_msg(msg);
534+ type = recv_msg(helper->fd, msg);
535 if (type == SSH2_AGENT_IDENTITIES_ANSWER) {
536 if ((r = sshbuf_get_u32(msg, &nkeys)) != 0)
537 fatal("%s: buffer error: %s", __func__, ssh_err(r));
538@@ -350,7 +549,7 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp,
539 __func__, ssh_err(r));
540 if ((r = sshkey_from_blob(blob, blen, &k)) != 0)
541 fatal("%s: bad key: %s", __func__, ssh_err(r));
542- wrap_key(k);
543+ wrap_key(helper, k);
544 (*keysp)[i] = k;
545 if (labelsp)
546 (*labelsp)[i] = label;
547@@ -371,22 +570,15 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp,
548 int
549 pkcs11_del_provider(char *name)
550 {
551- int r, ret = -1;
552- struct sshbuf *msg;
553-
554- if ((msg = sshbuf_new()) == NULL)
555- fatal("%s: sshbuf_new failed", __func__);
556- if ((r = sshbuf_put_u8(msg, SSH_AGENTC_REMOVE_SMARTCARD_KEY)) != 0 ||
557- (r = sshbuf_put_cstring(msg, name)) != 0 ||
558- (r = sshbuf_put_cstring(msg, "")) != 0)
559- fatal("%s: buffer error: %s", __func__, ssh_err(r));
560- send_msg(msg);
561- sshbuf_reset(msg);
562-
563- if (recv_msg(msg) == SSH_AGENT_SUCCESS)
564- ret = 0;
565- sshbuf_free(msg);
566- return (ret);
567+ struct helper *helper;
568+
569+ /*
570+ * ssh-agent deletes keys before calling this, so the helper entry
571+ * should be gone before we get here.
572+ */
573+ debug3("%s: delete %s", __func__, name);
574+ if ((helper = helper_by_provider(name)) != NULL)
575+ helper_terminate(helper);
576+ return 0;
577 }
578-
579 #endif /* ENABLE_PKCS11 */
580--
5812.41.0