summaryrefslogtreecommitdiff
path: root/sshkey.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2018-07-03 11:39:54 +0000
committerDamien Miller <djm@mindrot.org>2018-07-03 23:26:36 +1000
commit4ba0d54794814ec0de1ec87987d0c3b89379b436 (patch)
treeb8d904880f8927374b377b2e4d5661213c1138b6 /sshkey.c
parent95344c257412b51199ead18d54eaed5bafb75617 (diff)
upstream: Improve strictness and control over RSA-SHA2 signature
In ssh, when an agent fails to return a RSA-SHA2 signature when requested and falls back to RSA-SHA1 instead, retry the signature to ensure that the public key algorithm sent in the SSH_MSG_USERAUTH matches the one in the signature itself. In sshd, strictly enforce that the public key algorithm sent in the SSH_MSG_USERAUTH message matches what appears in the signature. Make the sshd_config PubkeyAcceptedKeyTypes and HostbasedAcceptedKeyTypes options control accepted signature algorithms (previously they selected supported key types). This allows these options to ban RSA-SHA1 in favour of RSA-SHA2. Add new signature algorithms "rsa-sha2-256-cert-v01@openssh.com" and "rsa-sha2-512-cert-v01@openssh.com" to force use of RSA-SHA2 signatures with certificate keys. feedback and ok markus@ OpenBSD-Commit-ID: c6e9f6d45eed8962ad502d315d7eaef32c419dde
Diffstat (limited to 'sshkey.c')
-rw-r--r--sshkey.c104
1 files changed, 83 insertions, 21 deletions
diff --git a/sshkey.c b/sshkey.c
index 7712fba23..455cf3d67 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshkey.c,v 1.64 2018/03/22 07:05:48 markus Exp $ */ 1/* $OpenBSD: sshkey.c,v 1.65 2018/07/03 11:39:54 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved. 4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved.
@@ -83,46 +83,64 @@ static int sshkey_from_blob_internal(struct sshbuf *buf,
83struct keytype { 83struct keytype {
84 const char *name; 84 const char *name;
85 const char *shortname; 85 const char *shortname;
86 const char *sigalg;
86 int type; 87 int type;
87 int nid; 88 int nid;
88 int cert; 89 int cert;
89 int sigonly; 90 int sigonly;
90}; 91};
91static const struct keytype keytypes[] = { 92static const struct keytype keytypes[] = {
92 { "ssh-ed25519", "ED25519", KEY_ED25519, 0, 0, 0 }, 93 { "ssh-ed25519", "ED25519", NULL, KEY_ED25519, 0, 0, 0 },
93 { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", 94 { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", NULL,
94 KEY_ED25519_CERT, 0, 1, 0 }, 95 KEY_ED25519_CERT, 0, 1, 0 },
95#ifdef WITH_XMSS 96#ifdef WITH_XMSS
96 { "ssh-xmss@openssh.com", "XMSS", KEY_XMSS, 0, 0, 0 }, 97 { "ssh-xmss@openssh.com", "XMSS", NULL, KEY_XMSS, 0, 0, 0 },
97 { "ssh-xmss-cert-v01@openssh.com", "XMSS-CERT", 98 { "ssh-xmss-cert-v01@openssh.com", "XMSS-CERT", NULL,
98 KEY_XMSS_CERT, 0, 1, 0 }, 99 KEY_XMSS_CERT, 0, 1, 0 },
99#endif /* WITH_XMSS */ 100#endif /* WITH_XMSS */
100#ifdef WITH_OPENSSL 101#ifdef WITH_OPENSSL
101 { "ssh-rsa", "RSA", KEY_RSA, 0, 0, 0 }, 102 { "ssh-rsa", "RSA", NULL, KEY_RSA, 0, 0, 0 },
102 { "rsa-sha2-256", "RSA", KEY_RSA, 0, 0, 1 }, 103 { "rsa-sha2-256", "RSA", NULL, KEY_RSA, 0, 0, 1 },
103 { "rsa-sha2-512", "RSA", KEY_RSA, 0, 0, 1 }, 104 { "rsa-sha2-512", "RSA", NULL, KEY_RSA, 0, 0, 1 },
104 { "ssh-dss", "DSA", KEY_DSA, 0, 0, 0 }, 105 { "ssh-dss", "DSA", NULL, KEY_DSA, 0, 0, 0 },
105# ifdef OPENSSL_HAS_ECC 106# ifdef OPENSSL_HAS_ECC
106 { "ecdsa-sha2-nistp256", "ECDSA", KEY_ECDSA, NID_X9_62_prime256v1, 0, 0 }, 107 { "ecdsa-sha2-nistp256", "ECDSA", NULL,
107 { "ecdsa-sha2-nistp384", "ECDSA", KEY_ECDSA, NID_secp384r1, 0, 0 }, 108 KEY_ECDSA, NID_X9_62_prime256v1, 0, 0 },
109 { "ecdsa-sha2-nistp384", "ECDSA", NULL,
110 KEY_ECDSA, NID_secp384r1, 0, 0 },
108# ifdef OPENSSL_HAS_NISTP521 111# ifdef OPENSSL_HAS_NISTP521
109 { "ecdsa-sha2-nistp521", "ECDSA", KEY_ECDSA, NID_secp521r1, 0, 0 }, 112 { "ecdsa-sha2-nistp521", "ECDSA", NULL,
113 KEY_ECDSA, NID_secp521r1, 0, 0 },
110# endif /* OPENSSL_HAS_NISTP521 */ 114# endif /* OPENSSL_HAS_NISTP521 */
111# endif /* OPENSSL_HAS_ECC */ 115# endif /* OPENSSL_HAS_ECC */
112 { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", KEY_RSA_CERT, 0, 1, 0 }, 116 { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", NULL,
113 { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", KEY_DSA_CERT, 0, 1, 0 }, 117 KEY_RSA_CERT, 0, 1, 0 },
118 { "rsa-sha2-256-cert-v01@openssh.com", "RSA-CERT",
119 "ssh-rsa-sha2-256", KEY_RSA_CERT, 0, 1, 1 },
120 { "rsa-sha2-512-cert-v01@openssh.com", "RSA-CERT",
121 "ssh-rsa-sha2-512", KEY_RSA_CERT, 0, 1, 1 },
122 { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", NULL,
123 KEY_DSA_CERT, 0, 1, 0 },
124 { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", NULL,
125 KEY_RSA_CERT, 0, 1, 0 },
126 { "rsa-sha2-256-cert-v01@openssh.com", "RSA-CERT",
127 "ssh-rsa-sha2-256", KEY_RSA_CERT, 0, 1, 1 },
128 { "rsa-sha2-512-cert-v01@openssh.com", "RSA-CERT",
129 "ssh-rsa-sha2-512", KEY_RSA_CERT, 0, 1, 1 },
130 { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", NULL,
131 KEY_DSA_CERT, 0, 1, 0 },
114# ifdef OPENSSL_HAS_ECC 132# ifdef OPENSSL_HAS_ECC
115 { "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT", 133 { "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT", NULL,
116 KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1, 0 }, 134 KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1, 0 },
117 { "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT", 135 { "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT", NULL,
118 KEY_ECDSA_CERT, NID_secp384r1, 1, 0 }, 136 KEY_ECDSA_CERT, NID_secp384r1, 1, 0 },
119# ifdef OPENSSL_HAS_NISTP521 137# ifdef OPENSSL_HAS_NISTP521
120 { "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT", 138 { "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT", NULL,
121 KEY_ECDSA_CERT, NID_secp521r1, 1, 0 }, 139 KEY_ECDSA_CERT, NID_secp521r1, 1, 0 },
122# endif /* OPENSSL_HAS_NISTP521 */ 140# endif /* OPENSSL_HAS_NISTP521 */
123# endif /* OPENSSL_HAS_ECC */ 141# endif /* OPENSSL_HAS_ECC */
124#endif /* WITH_OPENSSL */ 142#endif /* WITH_OPENSSL */
125 { NULL, NULL, -1, -1, 0, 0 } 143 { NULL, NULL, NULL, -1, -1, 0, 0 }
126}; 144};
127 145
128const char * 146const char *
@@ -2198,8 +2216,8 @@ sshkey_froms(struct sshbuf *buf, struct sshkey **keyp)
2198 return r; 2216 return r;
2199} 2217}
2200 2218
2201int 2219static int
2202sshkey_sigtype(const u_char *sig, size_t siglen, char **sigtypep) 2220get_sigtype(const u_char *sig, size_t siglen, char **sigtypep)
2203{ 2221{
2204 int r; 2222 int r;
2205 struct sshbuf *b = NULL; 2223 struct sshbuf *b = NULL;
@@ -2223,6 +2241,50 @@ sshkey_sigtype(const u_char *sig, size_t siglen, char **sigtypep)
2223 return r; 2241 return r;
2224} 2242}
2225 2243
2244/*
2245 * Returns the expected signature algorithm for a given public key algorithm.
2246 */
2247static const char *
2248sigalg_by_name(const char *name)
2249{
2250 const struct keytype *kt;
2251
2252 for (kt = keytypes; kt->type != -1; kt++) {
2253 if (strcmp(kt->name, name) != 0)
2254 continue;
2255 if (kt->sigalg != NULL)
2256 return kt->sigalg;
2257 if (!kt->cert)
2258 return kt->name;
2259 return sshkey_ssh_name_from_type_nid(
2260 sshkey_type_plain(kt->type), kt->nid);
2261 }
2262 return NULL;
2263}
2264
2265/*
2266 * Verifies that the signature algorithm appearing inside the signature blob
2267 * matches that which was requested.
2268 */
2269int
2270sshkey_check_sigtype(const u_char *sig, size_t siglen,
2271 const char *requested_alg)
2272{
2273 const char *expected_alg;
2274 char *sigtype = NULL;
2275 int r;
2276
2277 if (requested_alg == NULL)
2278 return 0;
2279 if ((expected_alg = sigalg_by_name(requested_alg)) == NULL)
2280 return SSH_ERR_INVALID_ARGUMENT;
2281 if ((r = get_sigtype(sig, siglen, &sigtype)) != 0)
2282 return r;
2283 r = strcmp(expected_alg, sigtype) == 0;
2284 free(sigtype);
2285 return r ? 0 : SSH_ERR_SIGN_ALG_UNSUPPORTED;
2286}
2287
2226int 2288int
2227sshkey_sign(const struct sshkey *key, 2289sshkey_sign(const struct sshkey *key,
2228 u_char **sigp, size_t *lenp, 2290 u_char **sigp, size_t *lenp,