diff options
author | djm@openbsd.org <djm@openbsd.org> | 2019-12-15 18:57:30 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2019-12-16 14:19:41 +1100 |
commit | 56584cce75f3d20aaa30befc7cbd331d922927f3 (patch) | |
tree | d3e9c2b7c9104b6528758b19eb7fa56dae2fcea6 /sshd.c | |
parent | 5af6fd5461bb709304e6979c8b7856c7af921c9e (diff) |
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
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 42 |
1 files changed, 35 insertions, 7 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.541 2019/11/18 16:10:05 naddy Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.542 2019/12/15 18:57:30 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -122,6 +122,7 @@ | |||
122 | #include "auth-options.h" | 122 | #include "auth-options.h" |
123 | #include "version.h" | 123 | #include "version.h" |
124 | #include "ssherr.h" | 124 | #include "ssherr.h" |
125 | #include "sk-api.h" | ||
125 | 126 | ||
126 | /* Re-exec fds */ | 127 | /* Re-exec fds */ |
127 | #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) | 128 | #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) |
@@ -632,6 +633,8 @@ list_hostkey_types(void) | |||
632 | case KEY_DSA: | 633 | case KEY_DSA: |
633 | case KEY_ECDSA: | 634 | case KEY_ECDSA: |
634 | case KEY_ED25519: | 635 | case KEY_ED25519: |
636 | case KEY_ECDSA_SK: | ||
637 | case KEY_ED25519_SK: | ||
635 | case KEY_XMSS: | 638 | case KEY_XMSS: |
636 | append_hostkey_type(b, sshkey_ssh_name(key)); | 639 | append_hostkey_type(b, sshkey_ssh_name(key)); |
637 | break; | 640 | break; |
@@ -651,6 +654,8 @@ list_hostkey_types(void) | |||
651 | case KEY_DSA_CERT: | 654 | case KEY_DSA_CERT: |
652 | case KEY_ECDSA_CERT: | 655 | case KEY_ECDSA_CERT: |
653 | case KEY_ED25519_CERT: | 656 | case KEY_ED25519_CERT: |
657 | case KEY_ECDSA_SK_CERT: | ||
658 | case KEY_ED25519_SK_CERT: | ||
654 | case KEY_XMSS_CERT: | 659 | case KEY_XMSS_CERT: |
655 | append_hostkey_type(b, sshkey_ssh_name(key)); | 660 | append_hostkey_type(b, sshkey_ssh_name(key)); |
656 | break; | 661 | break; |
@@ -675,6 +680,8 @@ get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) | |||
675 | case KEY_DSA_CERT: | 680 | case KEY_DSA_CERT: |
676 | case KEY_ECDSA_CERT: | 681 | case KEY_ECDSA_CERT: |
677 | case KEY_ED25519_CERT: | 682 | case KEY_ED25519_CERT: |
683 | case KEY_ECDSA_SK_CERT: | ||
684 | case KEY_ED25519_SK_CERT: | ||
678 | case KEY_XMSS_CERT: | 685 | case KEY_XMSS_CERT: |
679 | key = sensitive_data.host_certificates[i]; | 686 | key = sensitive_data.host_certificates[i]; |
680 | break; | 687 | break; |
@@ -684,10 +691,20 @@ get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) | |||
684 | key = sensitive_data.host_pubkeys[i]; | 691 | key = sensitive_data.host_pubkeys[i]; |
685 | break; | 692 | break; |
686 | } | 693 | } |
687 | if (key != NULL && key->type == type && | 694 | if (key == NULL || key->type != type) |
688 | (key->type != KEY_ECDSA || key->ecdsa_nid == nid)) | 695 | continue; |
696 | switch (type) { | ||
697 | case KEY_ECDSA: | ||
698 | case KEY_ECDSA_SK: | ||
699 | case KEY_ECDSA_CERT: | ||
700 | case KEY_ECDSA_SK_CERT: | ||
701 | if (key->ecdsa_nid != nid) | ||
702 | continue; | ||
703 | /* FALLTHROUGH */ | ||
704 | default: | ||
689 | return need_private ? | 705 | return need_private ? |
690 | sensitive_data.host_keys[i] : key; | 706 | sensitive_data.host_keys[i] : key; |
707 | } | ||
691 | } | 708 | } |
692 | return NULL; | 709 | return NULL; |
693 | } | 710 | } |
@@ -1723,7 +1740,14 @@ main(int ac, char **av) | |||
1723 | &key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR) | 1740 | &key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR) |
1724 | do_log2(ll, "Unable to load host key \"%s\": %s", | 1741 | do_log2(ll, "Unable to load host key \"%s\": %s", |
1725 | options.host_key_files[i], ssh_err(r)); | 1742 | options.host_key_files[i], ssh_err(r)); |
1726 | if (r == 0 && (r = sshkey_shield_private(key)) != 0) { | 1743 | if (sshkey_is_sk(key) && |
1744 | key->sk_flags & SSH_SK_USER_PRESENCE_REQD) { | ||
1745 | debug("host key %s requires user presence, ignoring", | ||
1746 | options.host_key_files[i]); | ||
1747 | key->sk_flags &= ~SSH_SK_USER_PRESENCE_REQD; | ||
1748 | } | ||
1749 | if (r == 0 && key != NULL && | ||
1750 | (r = sshkey_shield_private(key)) != 0) { | ||
1727 | do_log2(ll, "Unable to shield host key \"%s\": %s", | 1751 | do_log2(ll, "Unable to shield host key \"%s\": %s", |
1728 | options.host_key_files[i], ssh_err(r)); | 1752 | options.host_key_files[i], ssh_err(r)); |
1729 | sshkey_free(key); | 1753 | sshkey_free(key); |
@@ -1760,6 +1784,8 @@ main(int ac, char **av) | |||
1760 | case KEY_DSA: | 1784 | case KEY_DSA: |
1761 | case KEY_ECDSA: | 1785 | case KEY_ECDSA: |
1762 | case KEY_ED25519: | 1786 | case KEY_ED25519: |
1787 | case KEY_ECDSA_SK: | ||
1788 | case KEY_ED25519_SK: | ||
1763 | case KEY_XMSS: | 1789 | case KEY_XMSS: |
1764 | if (have_agent || key != NULL) | 1790 | if (have_agent || key != NULL) |
1765 | sensitive_data.have_ssh2_key = 1; | 1791 | sensitive_data.have_ssh2_key = 1; |
@@ -2212,17 +2238,19 @@ sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey, | |||
2212 | if (use_privsep) { | 2238 | if (use_privsep) { |
2213 | if (privkey) { | 2239 | if (privkey) { |
2214 | if (mm_sshkey_sign(ssh, privkey, signature, slenp, | 2240 | if (mm_sshkey_sign(ssh, privkey, signature, slenp, |
2215 | data, dlen, alg, NULL, ssh->compat) < 0) | 2241 | data, dlen, alg, options.sk_provider, |
2242 | ssh->compat) < 0) | ||
2216 | fatal("%s: privkey sign failed", __func__); | 2243 | fatal("%s: privkey sign failed", __func__); |
2217 | } else { | 2244 | } else { |
2218 | if (mm_sshkey_sign(ssh, pubkey, signature, slenp, | 2245 | if (mm_sshkey_sign(ssh, pubkey, signature, slenp, |
2219 | data, dlen, alg, NULL, ssh->compat) < 0) | 2246 | data, dlen, alg, options.sk_provider, |
2247 | ssh->compat) < 0) | ||
2220 | fatal("%s: pubkey sign failed", __func__); | 2248 | fatal("%s: pubkey sign failed", __func__); |
2221 | } | 2249 | } |
2222 | } else { | 2250 | } else { |
2223 | if (privkey) { | 2251 | if (privkey) { |
2224 | if (sshkey_sign(privkey, signature, slenp, data, dlen, | 2252 | if (sshkey_sign(privkey, signature, slenp, data, dlen, |
2225 | alg, NULL, ssh->compat) < 0) | 2253 | alg, options.sk_provider, ssh->compat) < 0) |
2226 | fatal("%s: privkey sign failed", __func__); | 2254 | fatal("%s: privkey sign failed", __func__); |
2227 | } else { | 2255 | } else { |
2228 | if ((r = ssh_agent_sign(auth_sock, pubkey, | 2256 | if ((r = ssh_agent_sign(auth_sock, pubkey, |