[openssh-commits] [openssh] 06/11: upstream: SK API and sk-helper error/PIN passing

git+noreply at mindrot.org git+noreply at mindrot.org
Mon Dec 30 21:17:39 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 c54cd1892c3e7f268b21e1f07ada9f0d9816ffc0
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Mon Dec 30 09:23:28 2019 +0000

    upstream: SK API and sk-helper error/PIN passing
    
    Allow passing a PIN via the SK API (API major crank) and let the
    ssh-sk-helper API follow.
    
    Also enhance the ssh-sk-helper API to support passing back an error
    code instead of a complete reply. Will be used to signal "wrong PIN",
    etc.
    
    feedback and ok markus@
    
    OpenBSD-Commit-ID: a1bd6b0a2421646919a0c139b8183ad76d28fb71
---
 sk-api.h        |   8 ++---
 sk-usbhid.c     |  10 +++---
 ssh-keygen.c    |   4 +--
 ssh-sk-client.c |  47 +++++++++++++++++++------
 ssh-sk-helper.c | 106 ++++++++++++++++++++++++++++++++++++++++++++------------
 ssh-sk.c        |  31 +++++++++--------
 ssh-sk.h        |  17 ++++++---
 sshkey.c        |   4 +--
 sshkey.h        |  10 +-----
 9 files changed, 165 insertions(+), 72 deletions(-)

diff --git a/sk-api.h b/sk-api.h
index 10f1fdb1..4f9f43ee 100644
--- a/sk-api.h
+++ b/sk-api.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sk-api.h,v 1.4 2019/12/30 09:21:16 djm Exp $ */
+/* $OpenBSD: sk-api.h,v 1.5 2019/12/30 09:23:28 djm Exp $ */
 /*
  * Copyright (c) 2019 Google LLC
  *
@@ -59,7 +59,7 @@ struct sk_resident_key {
 	struct sk_enroll_response key;
 };
 
-#define SSH_SK_VERSION_MAJOR		0x00020000 /* current API version */
+#define SSH_SK_VERSION_MAJOR		0x00030000 /* current API version */
 #define SSH_SK_VERSION_MAJOR_MASK	0xffff0000
 
 /* Return the version of the middleware API */
@@ -67,13 +67,13 @@ uint32_t sk_api_version(void);
 
 /* Enroll a U2F key (private key generation) */
 int sk_enroll(int alg, const uint8_t *challenge, size_t challenge_len,
-    const char *application, uint8_t flags,
+    const char *application, uint8_t flags, const char *pin,
     struct sk_enroll_response **enroll_response);
 
 /* Sign a challenge */
 int sk_sign(int alg, const uint8_t *message, size_t message_len,
     const char *application, const uint8_t *key_handle, size_t key_handle_len,
-    uint8_t flags, struct sk_sign_response **sign_response);
+    uint8_t flags, const char *pin, struct sk_sign_response **sign_response);
 
 /* Enumerate all resident keys */
 int sk_load_resident_keys(const char *pin,
diff --git a/sk-usbhid.c b/sk-usbhid.c
index fa442448..54ce0bdd 100644
--- a/sk-usbhid.c
+++ b/sk-usbhid.c
@@ -54,7 +54,7 @@
 	} while (0)
 #endif
 
-#define SK_VERSION_MAJOR	0x00020000 /* current API version */
+#define SK_VERSION_MAJOR	0x00030000 /* current API version */
 
 /* Flags */
 #define SK_USER_PRESENCE_REQD		0x01
@@ -105,13 +105,13 @@ uint32_t sk_api_version(void);
 
 /* Enroll a U2F key (private key generation) */
 int sk_enroll(int alg, const uint8_t *challenge, size_t challenge_len,
-    const char *application, uint8_t flags,
+    const char *application, uint8_t flags, const char *pin,
     struct sk_enroll_response **enroll_response);
 
 /* Sign a challenge */
 int sk_sign(int alg, const uint8_t *message, size_t message_len,
     const char *application, const uint8_t *key_handle, size_t key_handle_len,
-    uint8_t flags, struct sk_sign_response **sign_response);
+    uint8_t flags, const char *pin, struct sk_sign_response **sign_response);
 
 /* Load resident keys */
 int sk_load_resident_keys(const char *pin,
@@ -414,7 +414,7 @@ pack_public_key(int alg, const fido_cred_t *cred,
 
 int
 sk_enroll(int alg, const uint8_t *challenge, size_t challenge_len,
-    const char *application, uint8_t flags,
+    const char *application, uint8_t flags, const char *pin,
     struct sk_enroll_response **enroll_response)
 {
 	fido_cred_t *cred = NULL;
@@ -652,7 +652,7 @@ int
 sk_sign(int alg, const uint8_t *message, size_t message_len,
     const char *application,
     const uint8_t *key_handle, size_t key_handle_len,
-    uint8_t flags, struct sk_sign_response **sign_response)
+    uint8_t flags, const char *pin, struct sk_sign_response **sign_response)
 {
 	fido_assert_t *assert = NULL;
 	fido_dev_t *dev = NULL;
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 48342c09..79e2e92b 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keygen.c,v 1.377 2019/12/30 09:19:52 djm Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.378 2019/12/30 09:23:28 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1994 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -3368,7 +3368,7 @@ main(int argc, char **argv)
 		fflush(stdout);
 		if (sshsk_enroll(type, sk_provider,
  		    cert_key_id == NULL ? "ssh:" : cert_key_id,
- 		    sk_flags, NULL, &private, NULL) != 0)
+		    sk_flags, NULL, NULL, &private, NULL) != 0)
  			exit(1); /* error message already printed */
 		break;
 	default:
diff --git a/ssh-sk-client.c b/ssh-sk-client.c
index b2f06245..0033a665 100644
--- a/ssh-sk-client.c
+++ b/ssh-sk-client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-sk-client.c,v 1.2 2019/12/30 09:21:59 djm Exp $ */
+/* $OpenBSD: ssh-sk-client.c,v 1.3 2019/12/30 09:23:28 djm Exp $ */
 /*
  * Copyright (c) 2019 Google LLC
  *
@@ -21,6 +21,7 @@
 #include <sys/socket.h>
 #include <sys/wait.h>
 
+#include <limits.h>
 #include <errno.h>
 #include <signal.h>
 #include <stdarg.h>
@@ -128,14 +129,14 @@ reap_helper(pid_t pid)
 }
 
 static int
-client_converse(struct sshbuf *req, struct sshbuf **respp)
+client_converse(struct sshbuf *req, struct sshbuf **respp, u_int msg)
 {
 	int oerrno, fd, r2, r = SSH_ERR_INTERNAL_ERROR;
+	u_int rmsg, rerr;
 	pid_t pid;
 	u_char version;
 	void (*osigchld)(int);
 	struct sshbuf *resp = NULL;
-
 	*respp = NULL;
 
 	if ((r = start_helper(&fd, &pid, &osigchld)) != 0)
@@ -164,6 +165,28 @@ client_converse(struct sshbuf *req, struct sshbuf **respp)
 		r = SSH_ERR_INVALID_FORMAT;
 		goto out;
 	}
+	if ((r = sshbuf_get_u32(resp, &rmsg)) != 0) {
+		error("%s: parse message type: %s", __func__, ssh_err(r));
+		goto out;
+	}
+	if (rmsg == SSH_SK_HELPER_ERROR) {
+		if ((r = sshbuf_get_u32(resp, &rerr)) != 0) {
+			error("%s: parse error: %s", __func__, ssh_err(r));
+			goto out;
+		}
+		debug("%s: helper returned error -%u", __func__, rerr);
+		/* OpenSSH error values are negative; encoded as -err on wire */
+		if (rerr == 0 || rerr >= INT_MAX)
+			r = SSH_ERR_INTERNAL_ERROR;
+		else
+			r = -(int)rerr;
+		goto out;
+	} else if (rmsg != msg) {
+		error("%s: helper returned incorrect message type %u, "
+		    "expecting %u", __func__, rmsg, msg);
+		r = SSH_ERR_INTERNAL_ERROR;
+		goto out;
+	}
 	/* success */
 	r = 0;
  out:
@@ -189,7 +212,7 @@ client_converse(struct sshbuf *req, struct sshbuf **respp)
 int
 sshsk_sign(const char *provider, struct sshkey *key,
     u_char **sigp, size_t *lenp, const u_char *data, size_t datalen,
-    u_int compat)
+    u_int compat, const char *pin)
 {
 	int oerrno, r = SSH_ERR_INTERNAL_ERROR;
 	char *fp = NULL;
@@ -217,7 +240,8 @@ sshsk_sign(const char *provider, struct sshkey *key,
 	    (r = sshbuf_put_cstring(req, provider)) != 0 ||
 	    (r = sshbuf_put_string(req, data, datalen)) != 0 ||
 	    (r = sshbuf_put_cstring(req, NULL)) != 0 || /* alg */
-	    (r = sshbuf_put_u32(req, compat)) != 0) {
+	    (r = sshbuf_put_u32(req, compat)) != 0 ||
+	    (r = sshbuf_put_cstring(req, pin)) != 0) {
 		error("%s: compose: %s", __func__, ssh_err(r));
 		goto out;
 	}
@@ -228,7 +252,7 @@ sshsk_sign(const char *provider, struct sshkey *key,
 		r = SSH_ERR_ALLOC_FAIL;
 		goto out;
 	}
-	if ((r = client_converse(req, &resp)) != 0)
+	if ((r = client_converse(req, &resp, SSH_SK_HELPER_SIGN)) != 0)
 		goto out;
 
 	if ((r = sshbuf_get_string(resp, sigp, lenp)) != 0) {
@@ -259,8 +283,8 @@ sshsk_sign(const char *provider, struct sshkey *key,
 
 int
 sshsk_enroll(int type, const char *provider_path, const char *application,
-    uint8_t flags, struct sshbuf *challenge_buf, struct sshkey **keyp,
-    struct sshbuf *attest)
+    uint8_t flags, const char *pin, struct sshbuf *challenge_buf,
+    struct sshkey **keyp, struct sshbuf *attest)
 {
 	int oerrno, r = SSH_ERR_INTERNAL_ERROR;
 	struct sshbuf *kbuf = NULL, *abuf = NULL, *req = NULL, *resp = NULL;
@@ -289,12 +313,13 @@ sshsk_enroll(int type, const char *provider_path, const char *application,
 	    (r = sshbuf_put_cstring(req, provider_path)) != 0 ||
 	    (r = sshbuf_put_cstring(req, application)) != 0 ||
 	    (r = sshbuf_put_u8(req, flags)) != 0 ||
+	    (r = sshbuf_put_cstring(req, pin)) != 0 ||
 	    (r = sshbuf_put_stringb(req, challenge_buf)) != 0) {
 		error("%s: compose: %s", __func__, ssh_err(r));
 		goto out;
 	}
 
-	if ((r = client_converse(req, &resp)) != 0)
+	if ((r = client_converse(req, &resp, SSH_SK_HELPER_ENROLL)) != 0)
 		goto out;
 
 	if ((r = sshbuf_get_stringb(resp, kbuf)) != 0 ||
@@ -358,7 +383,7 @@ sshsk_load_resident(const char *provider_path, const char *pin,
 		goto out;
 	}
 
-	if ((r = client_converse(req, &resp)) != 0)
+	if ((r = client_converse(req, &resp, SSH_SK_HELPER_LOAD_RESIDENT)) != 0)
 		goto out;
 
 	while (sshbuf_len(resp) != 0) {
@@ -378,6 +403,8 @@ sshsk_load_resident(const char *provider_path, const char *pin,
 			error("%s: recallocarray keys failed", __func__);
 			goto out;
 		}
+		debug("%s: keys[%zu]: %s %s", __func__,
+		    nkeys, sshkey_type(key), key->sk_application);
 		keys = tmp;
 		keys[nkeys++] = key;
 		key = NULL;
diff --git a/ssh-sk-helper.c b/ssh-sk-helper.c
index ac528cfc..590ff850 100644
--- a/ssh-sk-helper.c
+++ b/ssh-sk-helper.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-sk-helper.c,v 1.5 2019/12/30 09:21:59 djm Exp $ */
+/* $OpenBSD: ssh-sk-helper.c,v 1.6 2019/12/30 09:23:28 djm Exp $ */
 /*
  * Copyright (c) 2019 Google LLC
  *
@@ -50,6 +50,33 @@
 #ifdef ENABLE_SK
 extern char *__progname;
 
+static struct sshbuf *reply_error(int r, char *fmt, ...)
+    __attribute__((__format__ (printf, 2, 3)));
+
+static struct sshbuf *
+reply_error(int r, char *fmt, ...)
+{
+	char *msg;
+	va_list ap;
+	struct sshbuf *resp;
+
+	va_start(ap, fmt);
+	xvasprintf(&msg, fmt, ap);
+	va_end(ap);
+	error("%s: %s", __progname, msg);
+	free(msg);
+
+	if (r >= 0)
+		fatal("%s: invalid error code %d", __func__, r);
+
+	if ((resp = sshbuf_new()) == NULL)
+		fatal("%s: sshbuf_new failed", __progname);
+	if (sshbuf_put_u32(resp, SSH_SK_HELPER_ERROR) != 0 ||
+	    sshbuf_put_u32(resp, (u_int)-r) != 0)
+		fatal("%s: buffer error", __progname);
+	return resp;
+}
+
 static struct sshbuf *
 process_sign(struct sshbuf *req)
 {
@@ -60,13 +87,14 @@ process_sign(struct sshbuf *req)
 	const u_char *message;
 	u_char *sig;
 	size_t msglen, siglen;
-	char *provider;
+	char *provider, *pin;
 
 	if ((r = sshbuf_froms(req, &kbuf)) != 0 ||
 	    (r = sshbuf_get_cstring(req, &provider, NULL)) != 0 ||
 	    (r = sshbuf_get_string_direct(req, &message, &msglen)) != 0 ||
 	    (r = sshbuf_get_cstring(req, NULL, NULL)) != 0 || /* alg */
-	    (r = sshbuf_get_u32(req, &compat)) != 0)
+	    (r = sshbuf_get_u32(req, &compat)) != 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);
@@ -80,19 +108,28 @@ process_sign(struct sshbuf *req)
 	    "msg len %zu, compat 0x%lx", __progname, sshkey_type(key),
 	    provider, msglen, (u_long)compat);
 
+	if (*pin == 0) {
+		free(pin);
+		pin = NULL;
+	}
+
 	if ((r = sshsk_sign(provider, key, &sig, &siglen,
-	    message, msglen, compat)) != 0)
-		fatal("Signing failed: %s", ssh_err(r));
+	    message, msglen, compat, pin)) != 0) {
+		resp = reply_error(r, "Signing failed: %s", ssh_err(r));
+		goto out;
+	}
 
 	if ((resp = sshbuf_new()) == NULL)
 		fatal("%s: sshbuf_new failed", __progname);
 
-	if ((r = sshbuf_put_string(resp, sig, siglen)) != 0)
+	if ((r = sshbuf_put_u32(resp, SSH_SK_HELPER_SIGN)) != 0 ||
+	    (r = sshbuf_put_string(resp, sig, siglen)) != 0)
 		fatal("%s: buffer error: %s", __progname, ssh_err(r));
-
+ out:
 	sshbuf_free(kbuf);
 	free(provider);
-
+	if (pin != NULL)
+		freezero(pin, strlen(pin));
 	return resp;
 }
 
@@ -101,14 +138,12 @@ process_enroll(struct sshbuf *req)
 {
 	int r;
 	u_int type;
-	char *provider;
-	char *application;
+	char *provider, *application, *pin;
 	uint8_t flags;
 	struct sshbuf *challenge, *attest, *kbuf, *resp;
 	struct sshkey *key;
 
-	if ((resp = sshbuf_new()) == NULL ||
-	    (attest = sshbuf_new()) == NULL ||
+	if ((attest = sshbuf_new()) == NULL ||
 	    (kbuf = sshbuf_new()) == NULL)
 		fatal("%s: sshbuf_new failed", __progname);
 
@@ -116,6 +151,7 @@ process_enroll(struct sshbuf *req)
 	    (r = sshbuf_get_cstring(req, &provider, NULL)) != 0 ||
 	    (r = sshbuf_get_cstring(req, &application, NULL)) != 0 ||
 	    (r = sshbuf_get_u8(req, &flags)) != 0 ||
+	    (r = sshbuf_get_cstring(req, &pin, NULL)) != 0 ||
 	    (r = sshbuf_froms(req, &challenge)) != 0)
 		fatal("%s: buffer error: %s", __progname, ssh_err(r));
 	if (sshbuf_len(req) != 0)
@@ -127,23 +163,35 @@ process_enroll(struct sshbuf *req)
 		sshbuf_free(challenge);
 		challenge = NULL;
 	}
+	if (*pin == 0) {
+		free(pin);
+		pin = NULL;
+	}
 
-	if ((r = sshsk_enroll((int)type, provider, application, flags,
-	    challenge, &key, attest)) != 0)
-		fatal("%s: sshsk_enroll failed: %s", __progname, ssh_err(r));
+	if ((r = sshsk_enroll((int)type, provider, application, flags, pin,
+	    challenge, &key, attest)) != 0) {
+		resp = reply_error(r, "Enrollment failed: %s", ssh_err(r));
+		goto out;
+	}
 
+	if ((resp = sshbuf_new()) == NULL)
+		fatal("%s: sshbuf_new failed", __progname);
 	if ((r = sshkey_private_serialize(key, kbuf)) != 0)
 		fatal("%s: serialize private key: %s", __progname, ssh_err(r));
-	if ((r = sshbuf_put_stringb(resp, kbuf)) != 0 ||
+	if ((r = sshbuf_put_u32(resp, SSH_SK_HELPER_ENROLL)) != 0 ||
+	    (r = sshbuf_put_stringb(resp, kbuf)) != 0 ||
 	    (r = sshbuf_put_stringb(resp, attest)) != 0)
 		fatal("%s: buffer error: %s", __progname, ssh_err(r));
 
+ out:
 	sshkey_free(key);
 	sshbuf_free(kbuf);
 	sshbuf_free(attest);
 	sshbuf_free(challenge);
 	free(provider);
 	free(application);
+	if (pin != NULL)
+		freezero(pin, strlen(pin));
 
 	return resp;
 }
@@ -157,8 +205,7 @@ process_load_resident(struct sshbuf *req)
 	struct sshkey **keys = NULL;
 	size_t nkeys = 0, i;
 
-	if ((resp = sshbuf_new()) == NULL ||
-	    (kbuf = sshbuf_new()) == NULL)
+	if ((kbuf = sshbuf_new()) == NULL)
 		fatal("%s: sshbuf_new failed", __progname);
 
 	if ((r = sshbuf_get_cstring(req, &provider, NULL)) != 0 ||
@@ -167,9 +214,22 @@ process_load_resident(struct sshbuf *req)
 	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));
+	if (*pin == 0) {
+		free(pin);
+		pin = NULL;
+	}
+
+	if ((r = sshsk_load_resident(provider, pin, &keys, &nkeys)) != 0) {
+		resp = reply_error(r, " sshsk_load_resident failed: %s",
+		    ssh_err(r));
+		goto out;
+	}
+
+	if ((resp = sshbuf_new()) == NULL)
+		fatal("%s: sshbuf_new failed", __progname);
+
+	if ((r = sshbuf_put_u32(resp, SSH_SK_HELPER_LOAD_RESIDENT)) != 0)
+		fatal("%s: buffer error: %s", __progname, ssh_err(r));
 
 	for (i = 0; i < nkeys; i++) {
 		debug("%s: key %zu %s %s", __func__, i,
@@ -183,12 +243,14 @@ process_load_resident(struct sshbuf *req)
 			fatal("%s: buffer error: %s", __progname, ssh_err(r));
 	}
 
+ out:
 	for (i = 0; i < nkeys; i++)
 		sshkey_free(keys[i]);
 	free(keys);
 	sshbuf_free(kbuf);
 	free(provider);
-	freezero(pin, strlen(pin));
+	if (pin != NULL)
+		freezero(pin, strlen(pin));
 	return resp;
 }
 
diff --git a/ssh-sk.c b/ssh-sk.c
index d48f34e3..a5d3c64d 100644
--- a/ssh-sk.c
+++ b/ssh-sk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-sk.c,v 1.20 2019/12/30 09:21:16 djm Exp $ */
+/* $OpenBSD: ssh-sk.c,v 1.21 2019/12/30 09:23:28 djm Exp $ */
 /*
  * Copyright (c) 2019 Google LLC
  *
@@ -53,13 +53,14 @@ struct sshsk_provider {
 	/* Enroll a U2F key (private key generation) */
 	int (*sk_enroll)(int alg, const uint8_t *challenge,
 	    size_t challenge_len, const char *application, uint8_t flags,
-	    struct sk_enroll_response **enroll_response);
+	    const char *pin, struct sk_enroll_response **enroll_response);
 
 	/* Sign a challenge */
 	int (*sk_sign)(int alg, const uint8_t *message, size_t message_len,
 	    const char *application,
 	    const uint8_t *key_handle, size_t key_handle_len,
-	    uint8_t flags, struct sk_sign_response **sign_response);
+	    uint8_t flags, const char *pin,
+	    struct sk_sign_response **sign_response);
 
 	/* Enumerate resident keys */
 	int (*sk_load_resident_keys)(const char *pin,
@@ -69,11 +70,11 @@ struct sshsk_provider {
 /* Built-in version */
 int ssh_sk_enroll(int alg, const uint8_t *challenge,
     size_t challenge_len, const char *application, uint8_t flags,
-    struct sk_enroll_response **enroll_response);
+    const char *pin, struct sk_enroll_response **enroll_response);
 int ssh_sk_sign(int alg, const uint8_t *message, size_t message_len,
     const char *application,
     const uint8_t *key_handle, size_t key_handle_len,
-    uint8_t flags, struct sk_sign_response **sign_response);
+    uint8_t flags, const char *pin, struct sk_sign_response **sign_response);
 int ssh_sk_load_resident_keys(const char *pin,
     struct sk_resident_key ***rks, size_t *nrks);
 
@@ -326,8 +327,8 @@ sshsk_key_from_response(int alg, const char *application, uint8_t flags,
 
 int
 sshsk_enroll(int type, const char *provider_path, const char *application,
-    uint8_t flags, struct sshbuf *challenge_buf, struct sshkey **keyp,
-    struct sshbuf *attest)
+    uint8_t flags, const char *pin, struct sshbuf *challenge_buf,
+    struct sshkey **keyp, struct sshbuf *attest)
 {
 	struct sshsk_provider *skp = NULL;
 	struct sshkey *key = NULL;
@@ -339,8 +340,9 @@ sshsk_enroll(int type, const char *provider_path, const char *application,
 	int alg;
 
 	debug("%s: provider \"%s\", application \"%s\", flags 0x%02x, "
-	    "challenge len %zu", __func__, provider_path, application,
-	    flags, challenge_buf == NULL ? 0 : sshbuf_len(challenge_buf));
+	    "challenge len %zu%s", __func__, provider_path, application,
+	    flags, challenge_buf == NULL ? 0 : sshbuf_len(challenge_buf),
+	    (pin != NULL && *pin != '\0') ? " with-pin" : "");
 
 	*keyp = NULL;
 	if (attest)
@@ -391,7 +393,7 @@ sshsk_enroll(int type, const char *provider_path, const char *application,
 	/* XXX validate flags? */
 	/* enroll key */
 	if ((r = skp->sk_enroll(alg, challenge, challenge_len, application,
-	    flags, &resp)) != 0) {
+	    flags, pin, &resp)) != 0) {
 		error("Security key provider %s returned failure %d",
 		    provider_path, r);
 		r = SSH_ERR_INVALID_FORMAT; /* XXX error codes in API? */
@@ -504,7 +506,7 @@ sshsk_ed25519_sig(struct sk_sign_response *resp, struct sshbuf *sig)
 int
 sshsk_sign(const char *provider_path, struct sshkey *key,
     u_char **sigp, size_t *lenp, const u_char *data, size_t datalen,
-    u_int compat)
+    u_int compat, const char *pin)
 {
 	struct sshsk_provider *skp = NULL;
 	int r = SSH_ERR_INTERNAL_ERROR;
@@ -513,8 +515,9 @@ sshsk_sign(const char *provider_path, struct sshkey *key,
 	struct sshbuf *inner_sig = NULL, *sig = NULL;
 	uint8_t message[32];
 
-	debug("%s: provider \"%s\", key %s, flags 0x%02x", __func__,
-	    provider_path, sshkey_type(key), key->sk_flags);
+	debug("%s: provider \"%s\", key %s, flags 0x%02x%s", __func__,
+	    provider_path, sshkey_type(key), key->sk_flags,
+	    (pin != NULL && *pin != '\0') ? " with-pin" : "");
 
 	if (sigp != NULL)
 		*sigp = NULL;
@@ -554,7 +557,7 @@ sshsk_sign(const char *provider_path, struct sshkey *key,
 	if ((r = skp->sk_sign(alg, message, sizeof(message),
 	    key->sk_application,
 	    sshbuf_ptr(key->sk_key_handle), sshbuf_len(key->sk_key_handle),
-	    key->sk_flags, &resp)) != 0) {
+	    key->sk_flags, pin, &resp)) != 0) {
 		debug("%s: sk_sign failed with code %d", __func__, r);
 		goto out;
 	}
diff --git a/ssh-sk.h b/ssh-sk.h
index 1afe839d..348759a9 100644
--- a/ssh-sk.h
+++ b/ssh-sk.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-sk.h,v 1.7 2019/12/30 09:21:16 djm Exp $ */
+/* $OpenBSD: ssh-sk.h,v 1.8 2019/12/30 09:23:28 djm Exp $ */
 /*
  * Copyright (c) 2019 Google LLC
  *
@@ -21,6 +21,15 @@
 struct sshbuf;
 struct sshkey;
 
+/* Version of protocol expected from ssh-sk-helper */
+#define SSH_SK_HELPER_VERSION		3
+
+/* ssh-sk-helper messages */
+#define SSH_SK_HELPER_ERROR		0	/* Only valid H->C */
+#define SSH_SK_HELPER_SIGN		1
+#define SSH_SK_HELPER_ENROLL		2
+#define SSH_SK_HELPER_LOAD_RESIDENT	3
+
 /*
  * Enroll (generate) a new security-key hosted private key of given type
  * via the specified provider middleware.
@@ -32,8 +41,8 @@ struct sshkey;
  * information is placed there.
  */
 int sshsk_enroll(int type, const char *provider_path, const char *application,
-    uint8_t flags, struct sshbuf *challenge_buf, struct sshkey **keyp,
-    struct sshbuf *attest);
+    uint8_t flags, const char *pin, struct sshbuf *challenge_buf,
+    struct sshkey **keyp, struct sshbuf *attest);
 
 /*
  * Calculate an ECDSA_SK or ED25519_SK signature using the specified key
@@ -43,7 +52,7 @@ int sshsk_enroll(int type, const char *provider_path, const char *application,
  */
 int sshsk_sign(const char *provider_path, struct sshkey *key,
     u_char **sigp, size_t *lenp, const u_char *data, size_t datalen,
-    u_int compat);
+    u_int compat, const char *pin);
 
 /*
  * Enumerates and loads all SSH-compatible resident keys from a security
diff --git a/sshkey.c b/sshkey.c
index 3bab2e89..6ccd0e0b 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.c,v 1.97 2019/12/13 19:09:10 djm Exp $ */
+/* $OpenBSD: sshkey.c,v 1.98 2019/12/30 09:23:28 djm Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2008 Alexander von Gernler.  All rights reserved.
@@ -2765,7 +2765,7 @@ sshkey_sign(struct sshkey *key,
 	case KEY_ECDSA_SK_CERT:
 	case KEY_ECDSA_SK:
 		r = sshsk_sign(sk_provider, key, sigp, lenp, data,
-		    datalen, compat);
+		    datalen, compat, /* XXX PIN */ NULL);
 		break;
 #ifdef WITH_XMSS
 	case KEY_XMSS:
diff --git a/sshkey.h b/sshkey.h
index 699c6b81..71a3fddc 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.h,v 1.43 2019/12/30 09:21:59 djm Exp $ */
+/* $OpenBSD: sshkey.h,v 1.44 2019/12/30 09:23:28 djm Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -51,14 +51,6 @@
 #define SSH_RSA_MINIMUM_MODULUS_SIZE	1024
 #define SSH_KEY_MAX_SIGN_DATA_SIZE	(1 << 20)
 
-/* Version of protocol expected from ssh-sk-helper */
-#define SSH_SK_HELPER_VERSION		2
-
-/* 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;
 
 /* Key types */

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


More information about the openssh-commits mailing list