upstream: implement loading of resident keys in ssh-sk-helper
feedback and ok markus@ OpenBSD-Commit-ID: b273c23769ea182c55c4a7b8f9cbd9181722011a
This commit is contained in:
parent
14cea36df3
commit
27753a8e21
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
3
sshkey.h
3
sshkey.h
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue