Bug Summary

File:src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c
Warning:line 259, column 7
Although the value stored to 'fp' is used in the enclosing expression, the value is never actually read from 'fp'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ssh-sk-client.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.bin/ssh/ssh-pkcs11-helper/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.bin/ssh/ssh-pkcs11-helper/.. -D WITH_OPENSSL -D WITH_ZLIB -D ENABLE_PKCS11 -D HAVE_DLOPEN -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/usr/src/usr.bin/ssh/ssh-pkcs11-helper/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c
1/* $OpenBSD: ssh-sk-client.c,v 1.10 2021/10/28 02:54:18 djm Exp $ */
2/*
3 * Copyright (c) 2019 Google LLC
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/types.h>
19#include <sys/socket.h>
20#include <sys/wait.h>
21
22#include <fcntl.h>
23#include <limits.h>
24#include <errno(*__errno()).h>
25#include <signal.h>
26#include <stdarg.h>
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <unistd.h>
31
32#include "log.h"
33#include "ssherr.h"
34#include "sshbuf.h"
35#include "sshkey.h"
36#include "msg.h"
37#include "digest.h"
38#include "pathnames.h"
39#include "ssh-sk.h"
40#include "misc.h"
41
42/* #define DEBUG_SK 1 */
43
44static int
45start_helper(int *fdp, pid_t *pidp, void (**osigchldp)(int))
46{
47 void (*osigchld)(int);
48 int oerrno, pair[2];
49 pid_t pid;
50 char *helper, *verbosity = NULL((void *)0);
51
52 *fdp = -1;
53 *pidp = 0;
54 *osigchldp = SIG_DFL(void (*)(int))0;
55
56 helper = getenv("SSH_SK_HELPER");
57 if (helper == NULL((void *)0) || strlen(helper) == 0)
58 helper = _PATH_SSH_SK_HELPER"/usr/libexec/ssh-sk-helper";
59 if (access(helper, X_OK0x01) != 0) {
60 oerrno = errno(*__errno());
61 error_f("helper \"%s\" unusable: %s", helper, strerror(errno))sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 61, 1, SYSLOG_LEVEL_ERROR, ((void *)0), "helper \"%s\" unusable: %s"
, helper, strerror((*__errno())))
;
62 errno(*__errno()) = oerrno;
63 return SSH_ERR_SYSTEM_ERROR-24;
64 }
65#ifdef DEBUG_SK
66 verbosity = "-vvv";
67#endif
68
69 /* Start helper */
70 if (socketpair(AF_UNIX1, SOCK_STREAM1, 0, pair) == -1) {
71 error("socketpair: %s", strerror(errno))sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 71, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "socketpair: %s"
, strerror((*__errno())))
;
72 return SSH_ERR_SYSTEM_ERROR-24;
73 }
74 osigchld = ssh_signal(SIGCHLD20, SIG_DFL(void (*)(int))0);
75 if ((pid = fork()) == -1) {
76 oerrno = errno(*__errno());
77 error("fork: %s", strerror(errno))sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 77, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "fork: %s"
, strerror((*__errno())))
;
78 close(pair[0]);
79 close(pair[1]);
80 ssh_signal(SIGCHLD20, osigchld);
81 errno(*__errno()) = oerrno;
82 return SSH_ERR_SYSTEM_ERROR-24;
83 }
84 if (pid == 0) {
85 if ((dup2(pair[1], STDIN_FILENO0) == -1) ||
86 (dup2(pair[1], STDOUT_FILENO1) == -1)) {
87 error_f("dup2: %s", strerror(errno))sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 87, 1, SYSLOG_LEVEL_ERROR, ((void *)0), "dup2: %s"
, strerror((*__errno())))
;
88 _exit(1);
89 }
90 close(pair[0]);
91 close(pair[1]);
92 closefrom(STDERR_FILENO2 + 1);
93 debug_f("starting %s %s", helper,sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 94, 1, SYSLOG_LEVEL_DEBUG1, ((void *)0), "starting %s %s"
, helper, verbosity == ((void *)0) ? "" : verbosity)
94 verbosity == NULL ? "" : verbosity)sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 94, 1, SYSLOG_LEVEL_DEBUG1, ((void *)0), "starting %s %s"
, helper, verbosity == ((void *)0) ? "" : verbosity)
;
95 execlp(helper, helper, verbosity, (char *)NULL((void *)0));
96 error_f("execlp: %s", strerror(errno))sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 96, 1, SYSLOG_LEVEL_ERROR, ((void *)0), "execlp: %s"
, strerror((*__errno())))
;
97 _exit(1);
98 }
99 close(pair[1]);
100
101 /* success */
102 debug3_f("started pid=%ld", (long)pid)sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 102, 1, SYSLOG_LEVEL_DEBUG3, ((void *)0), "started pid=%ld"
, (long)pid)
;
103 *fdp = pair[0];
104 *pidp = pid;
105 *osigchldp = osigchld;
106 return 0;
107}
108
109static int
110reap_helper(pid_t pid)
111{
112 int status, oerrno;
113
114 debug3_f("pid=%ld", (long)pid)sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 114, 1, SYSLOG_LEVEL_DEBUG3, ((void *)0), "pid=%ld"
, (long)pid)
;
115
116 errno(*__errno()) = 0;
117 while (waitpid(pid, &status, 0) == -1) {
118 if (errno(*__errno()) == EINTR4) {
119 errno(*__errno()) = 0;
120 continue;
121 }
122 oerrno = errno(*__errno());
123 error_f("waitpid: %s", strerror(errno))sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 123, 1, SYSLOG_LEVEL_ERROR, ((void *)0), "waitpid: %s"
, strerror((*__errno())))
;
124 errno(*__errno()) = oerrno;
125 return SSH_ERR_SYSTEM_ERROR-24;
126 }
127 if (!WIFEXITED(status)(((status) & 0177) == 0)) {
128 error_f("helper exited abnormally")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 128, 1, SYSLOG_LEVEL_ERROR, ((void *)0), "helper exited abnormally"
)
;
129 return SSH_ERR_AGENT_FAILURE-27;
130 } else if (WEXITSTATUS(status)(int)(((unsigned)(status) >> 8) & 0xff) != 0) {
131 error_f("helper exited with non-zero exit status")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 131, 1, SYSLOG_LEVEL_ERROR, ((void *)0), "helper exited with non-zero exit status"
)
;
132 return SSH_ERR_AGENT_FAILURE-27;
133 }
134 return 0;
135}
136
137static int
138client_converse(struct sshbuf *msg, struct sshbuf **respp, u_int type)
139{
140 int oerrno, fd, r2, ll, r = SSH_ERR_INTERNAL_ERROR-1;
141 u_int rtype, rerr;
142 pid_t pid;
143 u_char version;
144 void (*osigchld)(int);
145 struct sshbuf *req = NULL((void *)0), *resp = NULL((void *)0);
146 *respp = NULL((void *)0);
147
148 if ((r = start_helper(&fd, &pid, &osigchld)) != 0)
149 return r;
150
151 if ((req = sshbuf_new()) == NULL((void *)0) || (resp = sshbuf_new()) == NULL((void *)0)) {
152 r = SSH_ERR_ALLOC_FAIL-2;
153 goto out;
154 }
155 /* Request preamble: type, log_on_stderr, log_level */
156 ll = log_level_get();
157 if ((r = sshbuf_put_u32(req, type)) != 0 ||
158 (r = sshbuf_put_u8(req, log_is_on_stderr() != 0)) != 0 ||
159 (r = sshbuf_put_u32(req, ll < 0 ? 0 : ll)) != 0 ||
160 (r = sshbuf_putb(req, msg)) != 0) {
161 error_fr(r, "compose")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 161, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "compose"
)
;
162 goto out;
163 }
164 if ((r = ssh_msg_send(fd, SSH_SK_HELPER_VERSION5, req)) != 0) {
165 error_fr(r, "send")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 165, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "send")
;
166 goto out;
167 }
168 if ((r = ssh_msg_recv(fd, resp)) != 0) {
169 error_fr(r, "receive")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 169, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "receive"
)
;
170 goto out;
171 }
172 if ((r = sshbuf_get_u8(resp, &version)) != 0) {
173 error_fr(r, "parse version")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 173, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "parse version"
)
;
174 goto out;
175 }
176 if (version != SSH_SK_HELPER_VERSION5) {
177 error_f("unsupported version: got %u, expected %u",sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 178, 1, SYSLOG_LEVEL_ERROR, ((void *)0), "unsupported version: got %u, expected %u"
, version, 5)
178 version, SSH_SK_HELPER_VERSION)sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 178, 1, SYSLOG_LEVEL_ERROR, ((void *)0), "unsupported version: got %u, expected %u"
, version, 5)
;
179 r = SSH_ERR_INVALID_FORMAT-4;
180 goto out;
181 }
182 if ((r = sshbuf_get_u32(resp, &rtype)) != 0) {
183 error_fr(r, "parse message type")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 183, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "parse message type"
)
;
184 goto out;
185 }
186 if (rtype == SSH_SK_HELPER_ERROR0) {
187 if ((r = sshbuf_get_u32(resp, &rerr)) != 0) {
188 error_fr(r, "parse")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 188, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "parse")
;
189 goto out;
190 }
191 debug_f("helper returned error -%u", rerr)sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 191, 1, SYSLOG_LEVEL_DEBUG1, ((void *)0), "helper returned error -%u"
, rerr)
;
192 /* OpenSSH error values are negative; encoded as -err on wire */
193 if (rerr == 0 || rerr >= INT_MAX2147483647)
194 r = SSH_ERR_INTERNAL_ERROR-1;
195 else
196 r = -(int)rerr;
197 goto out;
198 } else if (rtype != type) {
199 error_f("helper returned incorrect message type %u, "sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 200, 1, SYSLOG_LEVEL_ERROR, ((void *)0), "helper returned incorrect message type %u, "
"expecting %u", rtype, type)
200 "expecting %u", rtype, type)sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 200, 1, SYSLOG_LEVEL_ERROR, ((void *)0), "helper returned incorrect message type %u, "
"expecting %u", rtype, type)
;
201 r = SSH_ERR_INTERNAL_ERROR-1;
202 goto out;
203 }
204 /* success */
205 r = 0;
206 out:
207 oerrno = errno(*__errno());
208 close(fd);
209 if ((r2 = reap_helper(pid)) != 0) {
210 if (r == 0) {
211 r = r2;
212 oerrno = errno(*__errno());
213 }
214 }
215 if (r == 0) {
216 *respp = resp;
217 resp = NULL((void *)0);
218 }
219 sshbuf_free(req);
220 sshbuf_free(resp);
221 ssh_signal(SIGCHLD20, osigchld);
222 errno(*__errno()) = oerrno;
223 return r;
224
225}
226
227int
228sshsk_sign(const char *provider, struct sshkey *key,
229 u_char **sigp, size_t *lenp, const u_char *data, size_t datalen,
230 u_int compat, const char *pin)
231{
232 int oerrno, r = SSH_ERR_INTERNAL_ERROR-1;
233 char *fp = NULL((void *)0);
234 struct sshbuf *kbuf = NULL((void *)0), *req = NULL((void *)0), *resp = NULL((void *)0);
235
236 *sigp = NULL((void *)0);
237 *lenp = 0;
238
239 if ((kbuf = sshbuf_new()) == NULL((void *)0) ||
240 (req = sshbuf_new()) == NULL((void *)0)) {
241 r = SSH_ERR_ALLOC_FAIL-2;
242 goto out;
243 }
244
245 if ((r = sshkey_private_serialize(key, kbuf)) != 0) {
246 error_fr(r, "encode key")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 246, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "encode key"
)
;
247 goto out;
248 }
249 if ((r = sshbuf_put_stringb(req, kbuf)) != 0 ||
250 (r = sshbuf_put_cstring(req, provider)) != 0 ||
251 (r = sshbuf_put_string(req, data, datalen)) != 0 ||
252 (r = sshbuf_put_cstring(req, NULL((void *)0))) != 0 || /* alg */
253 (r = sshbuf_put_u32(req, compat)) != 0 ||
254 (r = sshbuf_put_cstring(req, pin)) != 0) {
255 error_fr(r, "compose")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 255, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "compose"
)
;
256 goto out;
257 }
258
259 if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT2,
Although the value stored to 'fp' is used in the enclosing expression, the value is never actually read from 'fp'
260 SSH_FP_DEFAULT)) == NULL((void *)0)) {
261 error_f("sshkey_fingerprint failed")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 261, 1, SYSLOG_LEVEL_ERROR, ((void *)0), "sshkey_fingerprint failed"
)
;
262 r = SSH_ERR_ALLOC_FAIL-2;
263 goto out;
264 }
265 if ((r = client_converse(req, &resp, SSH_SK_HELPER_SIGN1)) != 0)
266 goto out;
267
268 if ((r = sshbuf_get_string(resp, sigp, lenp)) != 0) {
269 error_fr(r, "parse signature")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 269, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "parse signature"
)
;
270 r = SSH_ERR_INVALID_FORMAT-4;
271 goto out;
272 }
273 if (sshbuf_len(resp) != 0) {
274 error_f("trailing data in response")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 274, 1, SYSLOG_LEVEL_ERROR, ((void *)0), "trailing data in response"
)
;
275 r = SSH_ERR_INVALID_FORMAT-4;
276 goto out;
277 }
278 /* success */
279 r = 0;
280 out:
281 oerrno = errno(*__errno());
282 if (r != 0) {
283 freezero(*sigp, *lenp);
284 *sigp = NULL((void *)0);
285 *lenp = 0;
286 }
287 sshbuf_free(kbuf);
288 sshbuf_free(req);
289 sshbuf_free(resp);
290 errno(*__errno()) = oerrno;
291 return r;
292}
293
294int
295sshsk_enroll(int type, const char *provider_path, const char *device,
296 const char *application, const char *userid, uint8_t flags,
297 const char *pin, struct sshbuf *challenge_buf,
298 struct sshkey **keyp, struct sshbuf *attest)
299{
300 int oerrno, r = SSH_ERR_INTERNAL_ERROR-1;
301 struct sshbuf *kbuf = NULL((void *)0), *abuf = NULL((void *)0), *req = NULL((void *)0), *resp = NULL((void *)0);
302 struct sshkey *key = NULL((void *)0);
303
304 *keyp = NULL((void *)0);
305 if (attest != NULL((void *)0))
306 sshbuf_reset(attest);
307
308 if (type < 0)
309 return SSH_ERR_INVALID_ARGUMENT-10;
310
311 if ((abuf = sshbuf_new()) == NULL((void *)0) ||
312 (kbuf = sshbuf_new()) == NULL((void *)0) ||
313 (req = sshbuf_new()) == NULL((void *)0)) {
314 r = SSH_ERR_ALLOC_FAIL-2;
315 goto out;
316 }
317
318 if ((r = sshbuf_put_u32(req, (u_int)type)) != 0 ||
319 (r = sshbuf_put_cstring(req, provider_path)) != 0 ||
320 (r = sshbuf_put_cstring(req, device)) != 0 ||
321 (r = sshbuf_put_cstring(req, application)) != 0 ||
322 (r = sshbuf_put_cstring(req, userid)) != 0 ||
323 (r = sshbuf_put_u8(req, flags)) != 0 ||
324 (r = sshbuf_put_cstring(req, pin)) != 0 ||
325 (r = sshbuf_put_stringb(req, challenge_buf)) != 0) {
326 error_fr(r, "compose")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 326, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "compose"
)
;
327 goto out;
328 }
329
330 if ((r = client_converse(req, &resp, SSH_SK_HELPER_ENROLL2)) != 0)
331 goto out;
332
333 if ((r = sshbuf_get_stringb(resp, kbuf)) != 0 ||
334 (r = sshbuf_get_stringb(resp, abuf)) != 0) {
335 error_fr(r, "parse")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 335, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "parse")
;
336 r = SSH_ERR_INVALID_FORMAT-4;
337 goto out;
338 }
339 if (sshbuf_len(resp) != 0) {
340 error_f("trailing data in response")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 340, 1, SYSLOG_LEVEL_ERROR, ((void *)0), "trailing data in response"
)
;
341 r = SSH_ERR_INVALID_FORMAT-4;
342 goto out;
343 }
344 if ((r = sshkey_private_deserialize(kbuf, &key)) != 0) {
345 error_fr(r, "encode")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 345, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "encode")
;
346 goto out;
347 }
348 if (attest != NULL((void *)0) && (r = sshbuf_putb(attest, abuf)) != 0) {
349 error_fr(r, "encode attestation information")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 349, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "encode attestation information"
)
;
350 goto out;
351 }
352
353 /* success */
354 r = 0;
355 *keyp = key;
356 key = NULL((void *)0);
357 out:
358 oerrno = errno(*__errno());
359 sshkey_free(key);
360 sshbuf_free(kbuf);
361 sshbuf_free(abuf);
362 sshbuf_free(req);
363 sshbuf_free(resp);
364 errno(*__errno()) = oerrno;
365 return r;
366}
367
368static void
369sshsk_free_resident_key(struct sshsk_resident_key *srk)
370{
371 if (srk == NULL((void *)0))
372 return;
373 sshkey_free(srk->key);
374 freezero(srk->user_id, srk->user_id_len);
375 free(srk);
376}
377
378
379void
380sshsk_free_resident_keys(struct sshsk_resident_key **srks, size_t nsrks)
381{
382 size_t i;
383
384 if (srks == NULL((void *)0) || nsrks == 0)
385 return;
386
387 for (i = 0; i < nsrks; i++)
388 sshsk_free_resident_key(srks[i]);
389 free(srks);
390}
391
392int
393sshsk_load_resident(const char *provider_path, const char *device,
394 const char *pin, u_int flags, struct sshsk_resident_key ***srksp,
395 size_t *nsrksp)
396{
397 int oerrno, r = SSH_ERR_INTERNAL_ERROR-1;
398 struct sshbuf *kbuf = NULL((void *)0), *req = NULL((void *)0), *resp = NULL((void *)0);
399 struct sshkey *key = NULL((void *)0);
400 struct sshsk_resident_key *srk = NULL((void *)0), **srks = NULL((void *)0), **tmp;
401 u_char *userid = NULL((void *)0);
402 size_t userid_len = 0, nsrks = 0;
403
404 *srksp = NULL((void *)0);
405 *nsrksp = 0;
406
407 if ((resp = sshbuf_new()) == NULL((void *)0) ||
408 (kbuf = sshbuf_new()) == NULL((void *)0) ||
409 (req = sshbuf_new()) == NULL((void *)0)) {
410 r = SSH_ERR_ALLOC_FAIL-2;
411 goto out;
412 }
413
414 if ((r = sshbuf_put_cstring(req, provider_path)) != 0 ||
415 (r = sshbuf_put_cstring(req, device)) != 0 ||
416 (r = sshbuf_put_cstring(req, pin)) != 0 ||
417 (r = sshbuf_put_u32(req, flags)) != 0) {
418 error_fr(r, "compose")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 418, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "compose"
)
;
419 goto out;
420 }
421
422 if ((r = client_converse(req, &resp, SSH_SK_HELPER_LOAD_RESIDENT3)) != 0)
423 goto out;
424
425 while (sshbuf_len(resp) != 0) {
426 /* key, comment, user_id */
427 if ((r = sshbuf_get_stringb(resp, kbuf)) != 0 ||
428 (r = sshbuf_get_cstring(resp, NULL((void *)0), NULL((void *)0))) != 0 ||
429 (r = sshbuf_get_string(resp, &userid, &userid_len)) != 0) {
430 error_fr(r, "parse")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 430, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "parse")
;
431 r = SSH_ERR_INVALID_FORMAT-4;
432 goto out;
433 }
434 if ((r = sshkey_private_deserialize(kbuf, &key)) != 0) {
435 error_fr(r, "decode key")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 435, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "decode key"
)
;
436 goto out;
437 }
438 if ((srk = calloc(1, sizeof(*srk))) == NULL((void *)0)) {
439 error_f("calloc failed")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 439, 1, SYSLOG_LEVEL_ERROR, ((void *)0), "calloc failed"
)
;
440 goto out;
441 }
442 srk->key = key;
443 key = NULL((void *)0);
444 srk->user_id = userid;
445 srk->user_id_len = userid_len;
446 userid = NULL((void *)0);
447 userid_len = 0;
448 if ((tmp = recallocarray(srks, nsrks, nsrks + 1,
449 sizeof(*srks))) == NULL((void *)0)) {
450 error_f("recallocarray keys failed")sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 450, 1, SYSLOG_LEVEL_ERROR, ((void *)0), "recallocarray keys failed"
)
;
451 goto out;
452 }
453 debug_f("srks[%zu]: %s %s uidlen %zu", nsrks,sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 455, 1, SYSLOG_LEVEL_DEBUG1, ((void *)0), "srks[%zu]: %s %s uidlen %zu"
, nsrks, sshkey_type(srk->key), srk->key->sk_application
, srk->user_id_len)
454 sshkey_type(srk->key), srk->key->sk_application,sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 455, 1, SYSLOG_LEVEL_DEBUG1, ((void *)0), "srks[%zu]: %s %s uidlen %zu"
, nsrks, sshkey_type(srk->key), srk->key->sk_application
, srk->user_id_len)
455 srk->user_id_len)sshlog("/usr/src/usr.bin/ssh/ssh-pkcs11-helper/../ssh-sk-client.c"
, __func__, 455, 1, SYSLOG_LEVEL_DEBUG1, ((void *)0), "srks[%zu]: %s %s uidlen %zu"
, nsrks, sshkey_type(srk->key), srk->key->sk_application
, srk->user_id_len)
;
456 srks = tmp;
457 srks[nsrks++] = srk;
458 srk = NULL((void *)0);
459 }
460
461 /* success */
462 r = 0;
463 *srksp = srks;
464 *nsrksp = nsrks;
465 srks = NULL((void *)0);
466 nsrks = 0;
467 out:
468 oerrno = errno(*__errno());
469 sshsk_free_resident_key(srk);
470 sshsk_free_resident_keys(srks, nsrks);
471 freezero(userid, userid_len);
472 sshkey_free(key);
473 sshbuf_free(kbuf);
474 sshbuf_free(req);
475 sshbuf_free(resp);
476 errno(*__errno()) = oerrno;
477 return r;
478}