upstream: implement loading of resident keys in ssh-sk-helper

feedback and ok markus@

OpenBSD-Commit-ID: b273c23769ea182c55c4a7b8f9cbd9181722011a
This commit is contained in:
djm@openbsd.org 2019-12-30 09:21:59 +00:00 committed by Damien Miller
parent 14cea36df3
commit 27753a8e21
3 changed files with 121 additions and 3 deletions

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-sk-client.c,v 1.1 2019/12/13 20:16:56 djm Exp $ */
/* $OpenBSD: ssh-sk-client.c,v 1.2 2019/12/30 09:21:59 djm Exp $ */
/*
* Copyright (c) 2019 Google LLC
*
@ -331,3 +331,73 @@ sshsk_enroll(int type, const char *provider_path, const char *application,
errno = oerrno;
return r;
}
int
sshsk_load_resident(const char *provider_path, const char *pin,
struct sshkey ***keysp, size_t *nkeysp)
{
int oerrno, r = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *kbuf = NULL, *req = NULL, *resp = NULL;
struct sshkey *key = NULL, **keys = NULL, **tmp;
size_t i, nkeys = 0;
*keysp = NULL;
*nkeysp = 0;
if ((resp = sshbuf_new()) == NULL ||
(kbuf = sshbuf_new()) == NULL ||
(req = sshbuf_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((r = sshbuf_put_u32(req, SSH_SK_HELPER_LOAD_RESIDENT)) != 0 ||
(r = sshbuf_put_cstring(req, provider_path)) != 0 ||
(r = sshbuf_put_cstring(req, pin)) != 0) {
error("%s: compose: %s", __func__, ssh_err(r));
goto out;
}
if ((r = client_converse(req, &resp)) != 0)
goto out;
while (sshbuf_len(resp) != 0) {
/* key, comment */
if ((r = sshbuf_get_stringb(resp, kbuf)) != 0 ||
(r = sshbuf_get_cstring(resp, NULL, NULL)) != 0) {
error("%s: parse signature: %s", __func__, ssh_err(r));
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
if ((r = sshkey_private_deserialize(kbuf, &key)) != 0) {
error("Unable to parse private key: %s", ssh_err(r));
goto out;
}
if ((tmp = recallocarray(keys, nkeys, nkeys + 1,
sizeof(*keys))) == NULL) {
error("%s: recallocarray keys failed", __func__);
goto out;
}
keys = tmp;
keys[nkeys++] = key;
key = NULL;
}
/* success */
r = 0;
*keysp = keys;
*nkeysp = nkeys;
keys = NULL;
nkeys = 0;
out:
oerrno = errno;
for (i = 0; i < nkeys; i++)
sshkey_free(keys[i]);
free(keys);
sshkey_free(key);
sshbuf_free(kbuf);
sshbuf_free(req);
sshbuf_free(resp);
errno = oerrno;
return r;
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-sk-helper.c,v 1.4 2019/12/13 19:11:14 djm Exp $ */
/* $OpenBSD: ssh-sk-helper.c,v 1.5 2019/12/30 09:21:59 djm Exp $ */
/*
* Copyright (c) 2019 Google LLC
*
@ -148,6 +148,50 @@ process_enroll(struct sshbuf *req)
return resp;
}
static struct sshbuf *
process_load_resident(struct sshbuf *req)
{
int r;
char *provider, *pin;
struct sshbuf *kbuf, *resp;
struct sshkey **keys = NULL;
size_t nkeys = 0, i;
if ((resp = sshbuf_new()) == NULL ||
(kbuf = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __progname);
if ((r = sshbuf_get_cstring(req, &provider, NULL)) != 0 ||
(r = sshbuf_get_cstring(req, &pin, NULL)) != 0)
fatal("%s: buffer error: %s", __progname, ssh_err(r));
if (sshbuf_len(req) != 0)
fatal("%s: trailing data in request", __progname);
if ((r = sshsk_load_resident(provider, pin, &keys, &nkeys)) != 0)
fatal("%s: sshsk_load_resident failed: %s",
__progname, ssh_err(r));
for (i = 0; i < nkeys; i++) {
debug("%s: key %zu %s %s", __func__, i,
sshkey_type(keys[i]), keys[i]->sk_application);
sshbuf_reset(kbuf);
if ((r = sshkey_private_serialize(keys[i], kbuf)) != 0)
fatal("%s: serialize private key: %s",
__progname, ssh_err(r));
if ((r = sshbuf_put_stringb(resp, kbuf)) != 0 ||
(r = sshbuf_put_cstring(resp, "")) != 0) /* comment */
fatal("%s: buffer error: %s", __progname, ssh_err(r));
}
for (i = 0; i < nkeys; i++)
sshkey_free(keys[i]);
free(keys);
sshbuf_free(kbuf);
free(provider);
freezero(pin, strlen(pin));
return resp;
}
int
main(int argc, char **argv)
{
@ -212,6 +256,9 @@ main(int argc, char **argv)
case SSH_SK_HELPER_ENROLL:
resp = process_enroll(req);
break;
case SSH_SK_HELPER_LOAD_RESIDENT:
resp = process_load_resident(req);
break;
default:
fatal("%s: unsupported request type %u", __progname, rtype);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshkey.h,v 1.42 2019/12/13 19:11:14 djm Exp $ */
/* $OpenBSD: sshkey.h,v 1.43 2019/12/30 09:21:59 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -57,6 +57,7 @@
/* ssh-sk-helper messages */
#define SSH_SK_HELPER_SIGN 1
#define SSH_SK_HELPER_ENROLL 2
#define SSH_SK_HELPER_LOAD_RESIDENT 3
struct sshbuf;