[openssh-commits] [openssh] 02/08: upstream: use ssh-sk-helper for all security key signing operations

git+noreply at mindrot.org git+noreply at mindrot.org
Sat Dec 14 08:41:05 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 b52ec0ba3983859514aa7b57d6100fa9759fe696
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Fri Dec 13 19:09:10 2019 +0000

    upstream: use ssh-sk-helper for all security key signing operations
    
    This extracts and refactors the client interface for ssh-sk-helper
    from ssh-agent and generalises it for use by the other programs.
    This means that most OpenSSH tools no longer need to link against
    libfido2 or directly interact with /dev/uhid*
    
    requested by, feedback and ok markus@
    
    OpenBSD-Commit-ID: 1abcd3aea9a7460eccfbf8ca154cdfa62f1dc93f
---
 ssh-agent.c | 160 ++++++++----------------------------------------------------
 ssh-sk.c    |   4 +-
 ssh-sk.h    |   7 +--
 sshkey.c    |  15 ++----
 sshkey.h    |   5 +-
 5 files changed, 33 insertions(+), 158 deletions(-)

diff --git a/ssh-agent.c b/ssh-agent.c
index 1d4b779f..09d12dc3 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-agent.c,v 1.250 2019/11/19 16:02:32 jmc Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.251 2019/12/13 19:09:10 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -90,7 +90,7 @@
 #include "ssherr.h"
 #include "pathnames.h"
 #include "ssh-pkcs11.h"
-#include "ssh-sk.h"
+#include "sk-api.h"
 
 #ifndef DEFAULT_PROVIDER_WHITELIST
 # define DEFAULT_PROVIDER_WHITELIST "/usr/lib*/*,/usr/local/lib*/*"
@@ -282,130 +282,6 @@ agent_decode_alg(struct sshkey *key, u_int flags)
 	return NULL;
 }
 
-static int
-provider_sign(const char *provider, struct sshkey *key,
-    u_char **sigp, size_t *lenp,
-    const u_char *data, size_t datalen,
-    const char *alg, u_int compat)
-{
-	int status, pair[2], r = SSH_ERR_INTERNAL_ERROR;
-	pid_t pid;
-	char *helper, *verbosity = NULL, *fp = NULL;
-	struct sshbuf *kbuf, *req, *resp;
-	u_char version;
-	struct notifier_ctx *notifier = NULL;
-
-	debug3("%s: start for provider %s", __func__, provider);
-
-	*sigp = NULL;
-	*lenp = 0;
-
-	helper = getenv("SSH_SK_HELPER");
-	if (helper == NULL || strlen(helper) == 0)
-		helper = _PATH_SSH_SK_HELPER;
-	if (log_level_get() >= SYSLOG_LEVEL_DEBUG1)
-		verbosity = "-vvv";
-
-	/* Start helper */
-	if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) {
-		error("socketpair: %s", strerror(errno));
-		return SSH_ERR_SYSTEM_ERROR;
-	}
-	if ((pid = fork()) == -1) {
-		error("fork: %s", strerror(errno));
-		close(pair[0]);
-		close(pair[1]);
-		return SSH_ERR_SYSTEM_ERROR;
-	}
-	if (pid == 0) {
-		if ((dup2(pair[1], STDIN_FILENO) == -1) ||
-		    (dup2(pair[1], STDOUT_FILENO) == -1))
-			fatal("%s: dup2: %s", __func__, ssh_err(r));
-		close(pair[0]);
-		close(pair[1]);
-		closefrom(STDERR_FILENO + 1);
-		debug("%s: starting %s %s", __func__, helper,
-		    verbosity == NULL ? "" : verbosity);
-		execlp(helper, helper, verbosity, (char *)NULL);
-		fatal("%s: execlp: %s", __func__, strerror(errno));
-	}
-	close(pair[1]);
-
-	if ((kbuf = sshbuf_new()) == NULL ||
-	    (req = sshbuf_new()) == NULL ||
-	    (resp = sshbuf_new()) == NULL)
-		fatal("%s: sshbuf_new failed", __func__);
-
-	if ((r = sshkey_private_serialize(key, kbuf)) != 0 ||
-	    (r = sshbuf_put_stringb(req, kbuf)) != 0 ||
-	    (r = sshbuf_put_cstring(req, provider)) != 0 ||
-	    (r = sshbuf_put_string(req, data, datalen)) != 0 ||
-	    (r = sshbuf_put_u32(req, compat)) != 0)
-		fatal("%s: compose: %s", __func__, ssh_err(r));
-
-	if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
-	    SSH_FP_DEFAULT)) == NULL)
-		fatal("%s: sshkey_fingerprint failed", __func__);
-	notifier = notify_start(0,
-	    "Confirm user presence for key %s %s", sshkey_type(key), fp);
-
-	if ((r = ssh_msg_send(pair[0], SSH_SK_HELPER_VERSION, req)) != 0) {
-		error("%s: send: %s", __func__, ssh_err(r));
-		goto out;
-	}
-	if ((r = ssh_msg_recv(pair[0], resp)) != 0) {
-		error("%s: receive: %s", __func__, ssh_err(r));
-		goto out;
-	}
-	if ((r = sshbuf_get_u8(resp, &version)) != 0) {
-		error("%s: parse version: %s", __func__, ssh_err(r));
-		goto out;
-	}
-	if (version != SSH_SK_HELPER_VERSION) {
-		error("%s: unsupported version: got %u, expected %u",
-		    __func__, version, SSH_SK_HELPER_VERSION);
-		r = SSH_ERR_INVALID_FORMAT;
-		goto out;
-	}
-	if ((r = sshbuf_get_string(resp, sigp, lenp)) != 0) {
-		error("%s: parse signature: %s", __func__, ssh_err(r));
-		r = SSH_ERR_INVALID_FORMAT;
-		goto out;
-	}
-	if (sshbuf_len(resp) != 0) {
-		error("%s: trailing data in response", __func__);
-		r = SSH_ERR_INVALID_FORMAT;
-		goto out;
-	}
-	/* success */
-	r = 0;
- out:
-	while (waitpid(pid, &status, 0) == -1) {
-		if (errno != EINTR)
-			fatal("%s: waitpid: %s", __func__, ssh_err(r));
-	}
-	notify_complete(notifier);
-	if (!WIFEXITED(status)) {
-		error("%s: helper %s exited abnormally", __func__, helper);
-		if (r == 0)
-			r = SSH_ERR_SYSTEM_ERROR;
-	} else if (WEXITSTATUS(status) != 0) {
-		error("%s: helper %s exited with non-zero exit status",
-		    __func__, helper);
-		if (r == 0)
-			r = SSH_ERR_SYSTEM_ERROR;
-	}
-	if (r != 0) {
-		freezero(*sigp, *lenp);
-		*sigp = NULL;
-		*lenp = 0;
-	}
-	sshbuf_free(kbuf);
-	sshbuf_free(req);
-	sshbuf_free(resp);
-	return r;
-}
-
 /* ssh2 only */
 static void
 process_sign_request2(SocketEntry *e)
@@ -415,9 +291,11 @@ process_sign_request2(SocketEntry *e)
 	size_t dlen, slen = 0;
 	u_int compat = 0, flags;
 	int r, ok = -1;
+	char *fp = NULL;
 	struct sshbuf *msg;
 	struct sshkey *key = NULL;
 	struct identity *id;
+	struct notifier_ctx *notifier = NULL;
 
 	if ((msg = sshbuf_new()) == NULL)
 		fatal("%s: sshbuf_new failed", __func__);
@@ -436,25 +314,27 @@ process_sign_request2(SocketEntry *e)
 		verbose("%s: user refused key", __func__);
 		goto send;
 	}
-	if (id->sk_provider != NULL) {
-		if ((r = provider_sign(id->sk_provider, id->key, &signature,
-		    &slen, data, dlen, agent_decode_alg(key, flags),
-		    compat)) != 0) {
-			error("%s: sign: %s", __func__, ssh_err(r));
-			goto send;
-		}
-	} else {
-		if ((r = sshkey_sign(id->key, &signature, &slen,
-		    data, dlen, agent_decode_alg(key, flags),
-		    NULL, compat)) != 0) {
-			error("%s: sshkey_sign: %s", __func__, ssh_err(r));
-			goto send;
-		}
+	if (sshkey_is_sk(id->key) &&
+	    (id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
+		if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
+		    SSH_FP_DEFAULT)) == NULL)
+			fatal("%s: fingerprint failed", __func__);
+		notifier = notify_start(0,
+		    "Confirm user presence for key %s %s",
+		    sshkey_type(id->key), fp);
+	}
+	if ((r = sshkey_sign(id->key, &signature, &slen,
+	    data, dlen, agent_decode_alg(key, flags),
+	    id->sk_provider, compat)) != 0) {
+		error("%s: sshkey_sign: %s", __func__, ssh_err(r));
+		goto send;
 	}
 	/* Success */
 	ok = 0;
  send:
+	notify_complete(notifier);
 	sshkey_free(key);
+	free(fp);
 	if (ok == 0) {
 		if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 ||
 		    (r = sshbuf_put_string(msg, signature, slen)) != 0)
diff --git a/ssh-sk.c b/ssh-sk.c
index 7c63536e..9e563735 100644
--- a/ssh-sk.c
+++ b/ssh-sk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-sk.c,v 1.17 2019/11/27 22:32:11 djm Exp $ */
+/* $OpenBSD: ssh-sk.c,v 1.18 2019/12/13 19:09:10 djm Exp $ */
 /*
  * Copyright (c) 2019 Google LLC
  *
@@ -464,7 +464,7 @@ sshsk_ed25519_sig(struct sk_sign_response *resp, struct sshbuf *sig)
 }
 
 int
-sshsk_sign(const char *provider_path, const struct sshkey *key,
+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)
 {
diff --git a/ssh-sk.h b/ssh-sk.h
index bb593160..4d667884 100644
--- a/ssh-sk.h
+++ b/ssh-sk.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-sk.h,v 1.5 2019/11/12 19:31:45 markus Exp $ */
+/* $OpenBSD: ssh-sk.h,v 1.6 2019/12/13 19:09:10 djm Exp $ */
 /*
  * Copyright (c) 2019 Google LLC
  *
@@ -21,9 +21,6 @@
 struct sshbuf;
 struct sshkey;
 
-/* Version of protocol between ssh-agent and ssh-sk-helper */
-#define SSH_SK_HELPER_VERSION	1
-
 /*
  * Enroll (generate) a new security-key hosted private key of given type
  * via the specified provider middleware.
@@ -44,7 +41,7 @@ int sshsk_enroll(int type, const char *provider_path, const char *application,
  *
  * Returns 0 on success or a ssherr.h error code on failure.
  */
-int sshsk_sign(const char *provider_path, const struct sshkey *key,
+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);
 
diff --git a/sshkey.c b/sshkey.c
index 920c0dc3..674303c3 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.c,v 1.96 2019/11/25 00:51:37 djm Exp $ */
+/* $OpenBSD: sshkey.c,v 1.97 2019/12/13 19:09:10 djm Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2008 Alexander von Gernler.  All rights reserved.
@@ -2750,13 +2750,6 @@ sshkey_sign(struct sshkey *key,
 	case KEY_ECDSA:
 		r = ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat);
 		break;
-#  ifdef ENABLE_SK
-	case KEY_ECDSA_SK_CERT:
-	case KEY_ECDSA_SK:
-		r = sshsk_sign(sk_provider, key, sigp, lenp, data, datalen,
-		    compat);
-		break;
-#  endif /* ENABLE_SK */
 # endif /* OPENSSL_HAS_ECC */
 	case KEY_RSA_CERT:
 	case KEY_RSA:
@@ -2770,8 +2763,10 @@ sshkey_sign(struct sshkey *key,
 #ifdef ENABLE_SK
 	case KEY_ED25519_SK:
 	case KEY_ED25519_SK_CERT:
-		r = sshsk_sign(sk_provider, key, sigp, lenp, data, datalen,
-		    compat);
+	case KEY_ECDSA_SK_CERT:
+	case KEY_ECDSA_SK:
+		r = sshsk_sign(sk_provider, key, sigp, lenp, data,
+		    datalen, compat);
 		break;
 #endif /* ENABLE_SK */
 #ifdef WITH_XMSS
diff --git a/sshkey.h b/sshkey.h
index 56c0a9cd..d96dcb8b 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.h,v 1.40 2019/11/25 00:51:37 djm Exp $ */
+/* $OpenBSD: sshkey.h,v 1.41 2019/12/13 19:09:10 djm Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -51,6 +51,9 @@
 #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	1
+
 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