diff options
author | djm@openbsd.org <djm@openbsd.org> | 2019-12-30 09:21:59 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2019-12-30 20:58:19 +1100 |
commit | 27753a8e21887d47fe6b5c78a4aed0efe558a850 (patch) | |
tree | 761ebebce5fb94c32eef432db246abd81865c7d0 /ssh-sk-client.c | |
parent | 14cea36df397677b8f8568204300ef654114fd76 (diff) |
upstream: implement loading of resident keys in ssh-sk-helper
feedback and ok markus@
OpenBSD-Commit-ID: b273c23769ea182c55c4a7b8f9cbd9181722011a
Diffstat (limited to 'ssh-sk-client.c')
-rw-r--r-- | ssh-sk-client.c | 72 |
1 files changed, 71 insertions, 1 deletions
diff --git a/ssh-sk-client.c b/ssh-sk-client.c index 8a7ac97c4..b2f062455 100644 --- a/ssh-sk-client.c +++ b/ssh-sk-client.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-sk-client.c,v 1.1 2019/12/13 20:16:56 djm Exp $ */ | 1 | /* $OpenBSD: ssh-sk-client.c,v 1.2 2019/12/30 09:21:59 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2019 Google LLC | 3 | * Copyright (c) 2019 Google LLC |
4 | * | 4 | * |
@@ -331,3 +331,73 @@ sshsk_enroll(int type, const char *provider_path, const char *application, | |||
331 | errno = oerrno; | 331 | errno = oerrno; |
332 | return r; | 332 | return r; |
333 | } | 333 | } |
334 | |||
335 | int | ||
336 | sshsk_load_resident(const char *provider_path, const char *pin, | ||
337 | struct sshkey ***keysp, size_t *nkeysp) | ||
338 | { | ||
339 | int oerrno, r = SSH_ERR_INTERNAL_ERROR; | ||
340 | struct sshbuf *kbuf = NULL, *req = NULL, *resp = NULL; | ||
341 | struct sshkey *key = NULL, **keys = NULL, **tmp; | ||
342 | size_t i, nkeys = 0; | ||
343 | |||
344 | *keysp = NULL; | ||
345 | *nkeysp = 0; | ||
346 | |||
347 | if ((resp = sshbuf_new()) == NULL || | ||
348 | (kbuf = sshbuf_new()) == NULL || | ||
349 | (req = sshbuf_new()) == NULL) { | ||
350 | r = SSH_ERR_ALLOC_FAIL; | ||
351 | goto out; | ||
352 | } | ||
353 | |||
354 | if ((r = sshbuf_put_u32(req, SSH_SK_HELPER_LOAD_RESIDENT)) != 0 || | ||
355 | (r = sshbuf_put_cstring(req, provider_path)) != 0 || | ||
356 | (r = sshbuf_put_cstring(req, pin)) != 0) { | ||
357 | error("%s: compose: %s", __func__, ssh_err(r)); | ||
358 | goto out; | ||
359 | } | ||
360 | |||
361 | if ((r = client_converse(req, &resp)) != 0) | ||
362 | goto out; | ||
363 | |||
364 | while (sshbuf_len(resp) != 0) { | ||
365 | /* key, comment */ | ||
366 | if ((r = sshbuf_get_stringb(resp, kbuf)) != 0 || | ||
367 | (r = sshbuf_get_cstring(resp, NULL, NULL)) != 0) { | ||
368 | error("%s: parse signature: %s", __func__, ssh_err(r)); | ||
369 | r = SSH_ERR_INVALID_FORMAT; | ||
370 | goto out; | ||
371 | } | ||
372 | if ((r = sshkey_private_deserialize(kbuf, &key)) != 0) { | ||
373 | error("Unable to parse private key: %s", ssh_err(r)); | ||
374 | goto out; | ||
375 | } | ||
376 | if ((tmp = recallocarray(keys, nkeys, nkeys + 1, | ||
377 | sizeof(*keys))) == NULL) { | ||
378 | error("%s: recallocarray keys failed", __func__); | ||
379 | goto out; | ||
380 | } | ||
381 | keys = tmp; | ||
382 | keys[nkeys++] = key; | ||
383 | key = NULL; | ||
384 | } | ||
385 | |||
386 | /* success */ | ||
387 | r = 0; | ||
388 | *keysp = keys; | ||
389 | *nkeysp = nkeys; | ||
390 | keys = NULL; | ||
391 | nkeys = 0; | ||
392 | out: | ||
393 | oerrno = errno; | ||
394 | for (i = 0; i < nkeys; i++) | ||
395 | sshkey_free(keys[i]); | ||
396 | free(keys); | ||
397 | sshkey_free(key); | ||
398 | sshbuf_free(kbuf); | ||
399 | sshbuf_free(req); | ||
400 | sshbuf_free(resp); | ||
401 | errno = oerrno; | ||
402 | return r; | ||
403 | } | ||