[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