[openssh-commits] [openssh] 04/11: upstream: implement loading of resident keys in ssh-sk-helper

git+noreply at mindrot.org git+noreply at mindrot.org
Mon Dec 30 21:17:37 AEDT 2019


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit 27753a8e21887d47fe6b5c78a4aed0efe558a850
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Mon Dec 30 09:21:59 2019 +0000

    upstream: implement loading of resident keys in ssh-sk-helper
    
    feedback and ok markus@
    
    OpenBSD-Commit-ID: b273c23769ea182c55c4a7b8f9cbd9181722011a
---
 ssh-sk-client.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 ssh-sk-helper.c | 49 ++++++++++++++++++++++++++++++++++++++-
 sshkey.h        |  3 ++-
 3 files changed, 121 insertions(+), 3 deletions(-)

diff --git a/ssh-sk-client.c b/ssh-sk-client.c
index 8a7ac97c..b2f06245 100644
--- a/ssh-sk-client.c
+++ b/ssh-sk-client.c
@@ -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;
+}
diff --git a/ssh-sk-helper.c b/ssh-sk-helper.c
index 3dc149b9..ac528cfc 100644
--- a/ssh-sk-helper.c
+++ b/ssh-sk-helper.c
@@ -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);
 	}
diff --git a/sshkey.h b/sshkey.h
index 21ac802d..699c6b81 100644
--- a/sshkey.h
+++ b/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;
 

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list