mirror of
git://anongit.mindrot.org/openssh.git
synced 2024-11-23 09:17:32 +08:00
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
This commit is contained in:
parent
5af6fd5461
commit
56584cce75
@ -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 &&
|
||||
|
@ -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 ||
|
||||
|
40
myproposal.h
40
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"
|
||||
|
@ -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);
|
||||
|
18
servconf.c
18
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 */
|
||||
|
@ -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 */
|
||||
|
42
sshd.c
42
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,
|
||||
|
Loading…
Reference in New Issue
Block a user