summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2019-12-15 19:57:30 +0100
committerDamien Miller <djm@mindrot.org>2019-12-16 04:19:41 +0100
commit56584cce75f3d20aaa30befc7cbd331d922927f3 (patch)
treed3e9c2b7c9104b6528758b19eb7fa56dae2fcea6
parentAllow clock_nanosleep_time64 in seccomp sandbox. (diff)
downloadopenssh-56584cce75f3d20aaa30befc7cbd331d922927f3.tar.xz
openssh-56584cce75f3d20aaa30befc7cbd331d922927f3.zip
upstream: allow security keys to act as host keys as well as user
keys. Previously we didn't do this because we didn't want to expose the attack surface presented by USB and FIDO protocol handling, but now that this is insulated behind ssh-sk-helper there is less risk. ok markus@ OpenBSD-Commit-ID: 77b068dd133b8d87e0f010987bd5131e640ee64c
-rw-r--r--monitor.c4
-rw-r--r--monitor_wrap.c4
-rw-r--r--myproposal.h40
-rw-r--r--readconf.c4
-rw-r--r--servconf.c18
-rw-r--r--servconf.h3
-rw-r--r--sshd.c42
7 files changed, 67 insertions, 48 deletions
diff --git a/monitor.c b/monitor.c
index 64eca98d6..6ee44204c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.c,v 1.205 2019/11/25 10:23:36 djm Exp $ */
+/* $OpenBSD: monitor.c,v 1.206 2019/12/15 18:57:30 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -679,7 +679,7 @@ mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m)
if ((key = get_hostkey_by_index(keyid)) != NULL) {
if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, alg,
- NULL, compat)) != 0)
+ options.sk_provider, compat)) != 0)
fatal("%s: sshkey_sign failed: %s",
__func__, ssh_err(r));
} else if ((key = get_hostkey_public_by_index(keyid, ssh)) != NULL &&
diff --git a/monitor_wrap.c b/monitor_wrap.c
index 06599e3b1..001a8fa1c 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_wrap.c,v 1.116 2019/11/25 00:51:37 djm Exp $ */
+/* $OpenBSD: monitor_wrap.c,v 1.117 2019/12/15 18:57:30 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -224,8 +224,6 @@ mm_sshkey_sign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp,
int r;
debug3("%s entering", __func__);
- if (sk_provider != NULL)
- fatal("%s: sk_provider != NULL", __func__);
if ((m = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
if ((r = sshbuf_put_u32(m, ndx)) != 0 ||
diff --git a/myproposal.h b/myproposal.h
index b393db8b0..6688c3066 100644
--- a/myproposal.h
+++ b/myproposal.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: myproposal.h,v 1.62 2019/12/10 22:43:19 djm Exp $ */
+/* $OpenBSD: myproposal.h,v 1.63 2019/12/15 18:57:30 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -39,32 +39,30 @@
# define HOSTKEY_ECDSA_CERT_METHODS \
"ecdsa-sha2-nistp256-cert-v01@openssh.com," \
"ecdsa-sha2-nistp384-cert-v01@openssh.com," \
- "ecdsa-sha2-nistp521-cert-v01@openssh.com,"
+ "ecdsa-sha2-nistp521-cert-v01@openssh.com," \
+ "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,"
# define HOSTKEY_ECDSA_METHODS \
"ecdsa-sha2-nistp256," \
"ecdsa-sha2-nistp384," \
- "ecdsa-sha2-nistp521,"
+ "ecdsa-sha2-nistp521," \
+ "sk-ecdsa-sha2-nistp256@openssh.com,"
# else /* OPENSSL_HAS_NISTP521 */
# define KEX_ECDH_METHODS \
"ecdh-sha2-nistp256," \
"ecdh-sha2-nistp384,"
# define HOSTKEY_ECDSA_CERT_METHODS \
"ecdsa-sha2-nistp256-cert-v01@openssh.com," \
- "ecdsa-sha2-nistp384-cert-v01@openssh.com,"
+ "ecdsa-sha2-nistp384-cert-v01@openssh.com," \
+ "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,"
# define HOSTKEY_ECDSA_METHODS \
"ecdsa-sha2-nistp256," \
- "ecdsa-sha2-nistp384,"
-# endif /* OPENSSL_HAS_NISTP521 */
-# define USERKEY_ECDSA_SK_CERT_METHODS \
- "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,"
-# define USERKEY_ECDSA_SK_METHODS \
+ "ecdsa-sha2-nistp384," \
"sk-ecdsa-sha2-nistp256@openssh.com,"
+# endif /* OPENSSL_HAS_NISTP521 */
#else /* OPENSSL_HAS_ECC */
# define KEX_ECDH_METHODS
# define HOSTKEY_ECDSA_CERT_METHODS
# define HOSTKEY_ECDSA_METHODS
-# define USERKEY_ECDSA_SK_CERT_METHODS
-# define USERKEY_ECDSA_SK_METHODS
#endif /* OPENSSL_HAS_ECC */
#ifdef OPENSSL_HAVE_EVPGCM
@@ -110,11 +108,13 @@
#define KEX_DEFAULT_PK_ALG \
HOSTKEY_ECDSA_CERT_METHODS \
"ssh-ed25519-cert-v01@openssh.com," \
+ "sk-ssh-ed25519-cert-v01@openssh.com," \
"rsa-sha2-512-cert-v01@openssh.com," \
"rsa-sha2-256-cert-v01@openssh.com," \
"ssh-rsa-cert-v01@openssh.com," \
HOSTKEY_ECDSA_METHODS \
"ssh-ed25519," \
+ "sk-ssh-ed25519@openssh.com," \
"rsa-sha2-512," \
"rsa-sha2-256," \
"ssh-rsa"
@@ -145,29 +145,12 @@
/* Not a KEX value, but here so all the algorithm defaults are together */
#define SSH_ALLOWED_CA_SIGALGS \
HOSTKEY_ECDSA_METHODS \
- USERKEY_ECDSA_SK_METHODS \
"ssh-ed25519," \
"sk-ssh-ed25519@openssh.com," \
"rsa-sha2-512," \
"rsa-sha2-256," \
"ssh-rsa"
-#define PUBKEY_DEFAULT_PK_ALG \
- USERKEY_ECDSA_SK_CERT_METHODS \
- HOSTKEY_ECDSA_CERT_METHODS \
- "sk-ssh-ed25519-cert-v01@openssh.com," \
- "ssh-ed25519-cert-v01@openssh.com," \
- "rsa-sha2-512-cert-v01@openssh.com," \
- "rsa-sha2-256-cert-v01@openssh.com," \
- "ssh-rsa-cert-v01@openssh.com," \
- USERKEY_ECDSA_SK_METHODS \
- HOSTKEY_ECDSA_METHODS \
- "sk-ssh-ed25519@openssh.com," \
- "ssh-ed25519," \
- "rsa-sha2-512," \
- "rsa-sha2-256," \
- "ssh-rsa"
-
#else /* WITH_OPENSSL */
#define KEX_SERVER_KEX \
@@ -176,7 +159,6 @@
#define KEX_DEFAULT_PK_ALG \
"ssh-ed25519-cert-v01@openssh.com," \
"ssh-ed25519"
-#define PUBKEY_DEFAULT_PK_ALG KEX_DEFAULT_PK_ALG
#define KEX_SERVER_ENCRYPT \
"chacha20-poly1305@openssh.com," \
"aes128-ctr,aes192-ctr,aes256-ctr"
diff --git a/readconf.c b/readconf.c
index c046e4dbf..4ea8ec566 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.314 2019/11/14 21:27:29 djm Exp $ */
+/* $OpenBSD: readconf.c,v 1.315 2019/12/15 18:57:30 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -2153,7 +2153,7 @@ fill_default_options(Options * options)
ASSEMBLE(macs, KEX_CLIENT_MAC, all_mac);
ASSEMBLE(kex_algorithms, KEX_CLIENT_KEX, all_kex);
ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key);
- ASSEMBLE(pubkey_key_types, PUBKEY_DEFAULT_PK_ALG, all_key);
+ ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key);
ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig);
#undef ASSEMBLE
free(all_cipher);
diff --git a/servconf.c b/servconf.c
index 1f3beab4a..30cd59840 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: servconf.c,v 1.354 2019/11/25 00:52:46 djm Exp $ */
+/* $OpenBSD: servconf.c,v 1.355 2019/12/15 18:57:30 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -171,6 +171,7 @@ initialize_server_options(ServerOptions *options)
options->authorized_keys_command = NULL;
options->authorized_keys_command_user = NULL;
options->revoked_keys_file = NULL;
+ options->sk_provider = NULL;
options->trusted_user_ca_keys = NULL;
options->authorized_principals_file = NULL;
options->authorized_principals_command = NULL;
@@ -211,7 +212,7 @@ assemble_algorithms(ServerOptions *o)
ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex);
ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, all_key);
ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key);
- ASSEMBLE(pubkey_key_types, PUBKEY_DEFAULT_PK_ALG, all_key);
+ ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key);
ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig);
#undef ASSEMBLE
free(all_cipher);
@@ -428,6 +429,8 @@ fill_default_server_options(ServerOptions *options)
options->disable_forwarding = 0;
if (options->expose_userauth_info == -1)
options->expose_userauth_info = 0;
+ if (options->sk_provider == NULL)
+ options->sk_provider = xstrdup("internal");
assemble_algorithms(options);
@@ -447,6 +450,7 @@ fill_default_server_options(ServerOptions *options)
CLEAR_ON_NONE(options->banner);
CLEAR_ON_NONE(options->trusted_user_ca_keys);
CLEAR_ON_NONE(options->revoked_keys_file);
+ CLEAR_ON_NONE(options->sk_provider);
CLEAR_ON_NONE(options->authorized_principals_file);
CLEAR_ON_NONE(options->adm_forced_command);
CLEAR_ON_NONE(options->chroot_directory);
@@ -512,7 +516,7 @@ typedef enum {
sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
sStreamLocalBindMask, sStreamLocalBindUnlink,
sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
- sExposeAuthInfo, sRDomain, sPubkeyAuthOptions,
+ sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider,
sDeprecated, sIgnore, sUnsupported
} ServerOpCodes;
@@ -662,6 +666,7 @@ static struct {
{ "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
{ "rdomain", sRDomain, SSHCFG_ALL },
{ "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
+ { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL },
{ NULL, sBadOption, 0 }
};
@@ -2025,6 +2030,10 @@ process_server_config_line(ServerOptions *options, char *line,
charptr = &options->revoked_keys_file;
goto parse_filename;
+ case sSecurityKeyProvider:
+ charptr = &options->sk_provider;
+ goto parse_filename;
+
case sIPQoS:
arg = strdelim(&cp);
if ((value = parse_ipqos(arg)) == -1)
@@ -2646,6 +2655,7 @@ dump_config(ServerOptions *o)
dump_cfg_string(sChrootDirectory, o->chroot_directory);
dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
+ dump_cfg_string(sSecurityKeyProvider, o->sk_provider);
dump_cfg_string(sAuthorizedPrincipalsFile,
o->authorized_principals_file);
dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0'
@@ -2664,7 +2674,7 @@ dump_config(ServerOptions *o)
dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ?
o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG);
dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ?
- o->pubkey_key_types : PUBKEY_DEFAULT_PK_ALG);
+ o->pubkey_key_types : KEX_DEFAULT_PK_ALG);
dump_cfg_string(sRDomain, o->routing_domain);
/* string arguments requiring a lookup */
diff --git a/servconf.h b/servconf.h
index 9f202260a..6fc1efb2c 100644
--- a/servconf.h
+++ b/servconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.h,v 1.141 2019/11/25 00:52:46 djm Exp $ */
+/* $OpenBSD: servconf.h,v 1.142 2019/12/15 18:57:30 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -215,6 +215,7 @@ typedef struct {
int fingerprint_hash;
int expose_userauth_info;
u_int64_t timing_secret;
+ char *sk_provider;
} ServerOptions;
/* Information about the incoming connection as used by Match */
diff --git a/sshd.c b/sshd.c
index 1e4d8a295..0cf13a741 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.541 2019/11/18 16:10:05 naddy Exp $ */
+/* $OpenBSD: sshd.c,v 1.542 2019/12/15 18:57:30 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -122,6 +122,7 @@
#include "auth-options.h"
#include "version.h"
#include "ssherr.h"
+#include "sk-api.h"
/* Re-exec fds */
#define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1)
@@ -632,6 +633,8 @@ list_hostkey_types(void)
case KEY_DSA:
case KEY_ECDSA:
case KEY_ED25519:
+ case KEY_ECDSA_SK:
+ case KEY_ED25519_SK:
case KEY_XMSS:
append_hostkey_type(b, sshkey_ssh_name(key));
break;
@@ -651,6 +654,8 @@ list_hostkey_types(void)
case KEY_DSA_CERT:
case KEY_ECDSA_CERT:
case KEY_ED25519_CERT:
+ case KEY_ECDSA_SK_CERT:
+ case KEY_ED25519_SK_CERT:
case KEY_XMSS_CERT:
append_hostkey_type(b, sshkey_ssh_name(key));
break;
@@ -675,6 +680,8 @@ get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh)
case KEY_DSA_CERT:
case KEY_ECDSA_CERT:
case KEY_ED25519_CERT:
+ case KEY_ECDSA_SK_CERT:
+ case KEY_ED25519_SK_CERT:
case KEY_XMSS_CERT:
key = sensitive_data.host_certificates[i];
break;
@@ -684,10 +691,20 @@ get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh)
key = sensitive_data.host_pubkeys[i];
break;
}
- if (key != NULL && key->type == type &&
- (key->type != KEY_ECDSA || key->ecdsa_nid == nid))
+ if (key == NULL || key->type != type)
+ continue;
+ switch (type) {
+ case KEY_ECDSA:
+ case KEY_ECDSA_SK:
+ case KEY_ECDSA_CERT:
+ case KEY_ECDSA_SK_CERT:
+ if (key->ecdsa_nid != nid)
+ continue;
+ /* FALLTHROUGH */
+ default:
return need_private ?
sensitive_data.host_keys[i] : key;
+ }
}
return NULL;
}
@@ -1723,7 +1740,14 @@ main(int ac, char **av)
&key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR)
do_log2(ll, "Unable to load host key \"%s\": %s",
options.host_key_files[i], ssh_err(r));
- if (r == 0 && (r = sshkey_shield_private(key)) != 0) {
+ if (sshkey_is_sk(key) &&
+ key->sk_flags & SSH_SK_USER_PRESENCE_REQD) {
+ debug("host key %s requires user presence, ignoring",
+ options.host_key_files[i]);
+ key->sk_flags &= ~SSH_SK_USER_PRESENCE_REQD;
+ }
+ if (r == 0 && key != NULL &&
+ (r = sshkey_shield_private(key)) != 0) {
do_log2(ll, "Unable to shield host key \"%s\": %s",
options.host_key_files[i], ssh_err(r));
sshkey_free(key);
@@ -1760,6 +1784,8 @@ main(int ac, char **av)
case KEY_DSA:
case KEY_ECDSA:
case KEY_ED25519:
+ case KEY_ECDSA_SK:
+ case KEY_ED25519_SK:
case KEY_XMSS:
if (have_agent || key != NULL)
sensitive_data.have_ssh2_key = 1;
@@ -2212,17 +2238,19 @@ sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey,
if (use_privsep) {
if (privkey) {
if (mm_sshkey_sign(ssh, privkey, signature, slenp,
- data, dlen, alg, NULL, ssh->compat) < 0)
+ data, dlen, alg, options.sk_provider,
+ ssh->compat) < 0)
fatal("%s: privkey sign failed", __func__);
} else {
if (mm_sshkey_sign(ssh, pubkey, signature, slenp,
- data, dlen, alg, NULL, ssh->compat) < 0)
+ data, dlen, alg, options.sk_provider,
+ ssh->compat) < 0)
fatal("%s: pubkey sign failed", __func__);
}
} else {
if (privkey) {
if (sshkey_sign(privkey, signature, slenp, data, dlen,
- alg, NULL, ssh->compat) < 0)
+ alg, options.sk_provider, ssh->compat) < 0)
fatal("%s: privkey sign failed", __func__);
} else {
if ((r = ssh_agent_sign(auth_sock, pubkey,