summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2017-05-07 23:15:59 +0000
committerDamien Miller <djm@mindrot.org>2017-05-08 09:21:22 +1000
commitbd636f40911094a39c2920bf87d2ec340533c152 (patch)
tree53c4c9655827d6433a26a510f46081dfc4b72b6d
parent70c1218fc45757a030285051eb4d209403f54785 (diff)
upstream commit
Refuse RSA keys <1024 bits in length. Improve reporting for keys that do not meet this requirement. ok markus@ Upstream-ID: b385e2a7b13b1484792ee681daaf79e1e203df6c
-rw-r--r--ssh-keygen.c24
-rw-r--r--ssh-rsa.c10
-rw-r--r--ssh.h5
-rw-r--r--ssherr.c4
-rw-r--r--ssherr.h3
-rw-r--r--sshkey.c29
-rw-r--r--sshkey.h4
7 files changed, 54 insertions, 25 deletions
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 51c24bc55..7886582d7 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.302 2017/04/30 23:18:44 djm Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.303 2017/05/07 23:15:59 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -226,13 +226,21 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp)
226 OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; 226 OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS;
227 if (*bitsp > maxbits) 227 if (*bitsp > maxbits)
228 fatal("key bits exceeds maximum %d", maxbits); 228 fatal("key bits exceeds maximum %d", maxbits);
229 if (type == KEY_DSA && *bitsp != 1024) 229 switch (type) {
230 fatal("DSA keys must be 1024 bits"); 230 case KEY_DSA:
231 else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 1024) 231 if (*bitsp != 1024)
232 fatal("Key must at least be 1024 bits"); 232 fatal("Invalid DSA key length: must be 1024 bits");
233 else if (type == KEY_ECDSA && sshkey_ecdsa_bits_to_nid(*bitsp) == -1) 233 break;
234 fatal("Invalid ECDSA key length - valid lengths are " 234 case KEY_RSA:
235 "256, 384 or 521 bits"); 235 if (*bitsp < SSH_RSA_MINIMUM_MODULUS_SIZE)
236 fatal("Invalid RSA key length: minimum is %d bits",
237 SSH_RSA_MINIMUM_MODULUS_SIZE);
238 break;
239 case KEY_ECDSA:
240 if (sshkey_ecdsa_bits_to_nid(*bitsp) == -1)
241 fatal("Invalid ECDSA key length: valid lengths are "
242 "256, 384 or 521 bits");
243 }
236#endif 244#endif
237} 245}
238 246
diff --git a/ssh-rsa.c b/ssh-rsa.c
index cde05df10..e8acc01fa 100644
--- a/ssh-rsa.c
+++ b/ssh-rsa.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-rsa.c,v 1.60 2016/09/12 23:39:34 djm Exp $ */ 1/* $OpenBSD: ssh-rsa.c,v 1.61 2017/05/07 23:15:59 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org> 3 * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
4 * 4 *
@@ -99,9 +99,10 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
99 else 99 else
100 hash_alg = rsa_hash_alg_from_ident(alg_ident); 100 hash_alg = rsa_hash_alg_from_ident(alg_ident);
101 if (key == NULL || key->rsa == NULL || hash_alg == -1 || 101 if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
102 sshkey_type_plain(key->type) != KEY_RSA || 102 sshkey_type_plain(key->type) != KEY_RSA)
103 BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
104 return SSH_ERR_INVALID_ARGUMENT; 103 return SSH_ERR_INVALID_ARGUMENT;
104 if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
105 return SSH_ERR_KEY_LENGTH;
105 slen = RSA_size(key->rsa); 106 slen = RSA_size(key->rsa);
106 if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) 107 if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
107 return SSH_ERR_INVALID_ARGUMENT; 108 return SSH_ERR_INVALID_ARGUMENT;
@@ -172,9 +173,10 @@ ssh_rsa_verify(const struct sshkey *key,
172 173
173 if (key == NULL || key->rsa == NULL || 174 if (key == NULL || key->rsa == NULL ||
174 sshkey_type_plain(key->type) != KEY_RSA || 175 sshkey_type_plain(key->type) != KEY_RSA ||
175 BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE ||
176 sig == NULL || siglen == 0) 176 sig == NULL || siglen == 0)
177 return SSH_ERR_INVALID_ARGUMENT; 177 return SSH_ERR_INVALID_ARGUMENT;
178 if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
179 return SSH_ERR_KEY_LENGTH;
178 180
179 if ((b = sshbuf_from(sig, siglen)) == NULL) 181 if ((b = sshbuf_from(sig, siglen)) == NULL)
180 return SSH_ERR_ALLOC_FAIL; 182 return SSH_ERR_ALLOC_FAIL;
diff --git a/ssh.h b/ssh.h
index 08d05ce29..12d800922 100644
--- a/ssh.h
+++ b/ssh.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.h,v 1.86 2017/05/03 21:08:09 naddy Exp $ */ 1/* $OpenBSD: ssh.h,v 1.87 2017/05/07 23:15:59 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -98,8 +98,5 @@
98#define SSH_PRIVSEP_USER "sshd" 98#define SSH_PRIVSEP_USER "sshd"
99#endif 99#endif
100 100
101/* Minimum modulus size (n) for RSA keys. */
102#define SSH_RSA_MINIMUM_MODULUS_SIZE 768
103
104/* Listen backlog for sshd, ssh-agent and forwarding sockets */ 101/* Listen backlog for sshd, ssh-agent and forwarding sockets */
105#define SSH_LISTEN_BACKLOG 128 102#define SSH_LISTEN_BACKLOG 128
diff --git a/ssherr.c b/ssherr.c
index 680207063..4bd5f59cc 100644
--- a/ssherr.c
+++ b/ssherr.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssherr.c,v 1.5 2015/09/13 14:39:16 tim Exp $ */ 1/* $OpenBSD: ssherr.c,v 1.6 2017/05/07 23:15:59 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller 3 * Copyright (c) 2011 Damien Miller
4 * 4 *
@@ -135,6 +135,8 @@ ssh_err(int n)
135 return "Connection corrupted"; 135 return "Connection corrupted";
136 case SSH_ERR_PROTOCOL_ERROR: 136 case SSH_ERR_PROTOCOL_ERROR:
137 return "Protocol error"; 137 return "Protocol error";
138 case SSH_ERR_KEY_LENGTH:
139 return "Invalid key length";
138 default: 140 default:
139 return "unknown error"; 141 return "unknown error";
140 } 142 }
diff --git a/ssherr.h b/ssherr.h
index 6f771b4b7..a30781620 100644
--- a/ssherr.h
+++ b/ssherr.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssherr.h,v 1.3 2015/01/30 01:13:33 djm Exp $ */ 1/* $OpenBSD: ssherr.h,v 1.4 2017/05/07 23:15:59 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller 3 * Copyright (c) 2011 Damien Miller
4 * 4 *
@@ -77,6 +77,7 @@
77#define SSH_ERR_CONN_TIMEOUT -53 77#define SSH_ERR_CONN_TIMEOUT -53
78#define SSH_ERR_CONN_CORRUPT -54 78#define SSH_ERR_CONN_CORRUPT -54
79#define SSH_ERR_PROTOCOL_ERROR -55 79#define SSH_ERR_PROTOCOL_ERROR -55
80#define SSH_ERR_KEY_LENGTH -56
80 81
81/* Translate a numeric error code to a human-readable error string */ 82/* Translate a numeric error code to a human-readable error string */
82const char *ssh_err(int n); 83const char *ssh_err(int n);
diff --git a/sshkey.c b/sshkey.c
index 0f6468197..6518c6f0b 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshkey.c,v 1.48 2017/04/30 23:18:44 djm Exp $ */ 1/* $OpenBSD: sshkey.c,v 1.49 2017/05/07 23:15:59 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.
@@ -1392,10 +1392,11 @@ rsa_generate_private_key(u_int bits, RSA **rsap)
1392 BIGNUM *f4 = NULL; 1392 BIGNUM *f4 = NULL;
1393 int ret = SSH_ERR_INTERNAL_ERROR; 1393 int ret = SSH_ERR_INTERNAL_ERROR;
1394 1394
1395 if (rsap == NULL || 1395 if (rsap == NULL)
1396 bits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
1397 bits > SSHBUF_MAX_BIGNUM * 8)
1398 return SSH_ERR_INVALID_ARGUMENT; 1396 return SSH_ERR_INVALID_ARGUMENT;
1397 if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
1398 bits > SSHBUF_MAX_BIGNUM * 8)
1399 return SSH_ERR_KEY_LENGTH;
1399 *rsap = NULL; 1400 *rsap = NULL;
1400 if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) { 1401 if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) {
1401 ret = SSH_ERR_ALLOC_FAIL; 1402 ret = SSH_ERR_ALLOC_FAIL;
@@ -1423,8 +1424,10 @@ dsa_generate_private_key(u_int bits, DSA **dsap)
1423 DSA *private; 1424 DSA *private;
1424 int ret = SSH_ERR_INTERNAL_ERROR; 1425 int ret = SSH_ERR_INTERNAL_ERROR;
1425 1426
1426 if (dsap == NULL || bits != 1024) 1427 if (dsap == NULL)
1427 return SSH_ERR_INVALID_ARGUMENT; 1428 return SSH_ERR_INVALID_ARGUMENT;
1429 if (bits != 1024)
1430 return SSH_ERR_KEY_LENGTH;
1428 if ((private = DSA_new()) == NULL) { 1431 if ((private = DSA_new()) == NULL) {
1429 ret = SSH_ERR_ALLOC_FAIL; 1432 ret = SSH_ERR_ALLOC_FAIL;
1430 goto out; 1433 goto out;
@@ -1876,6 +1879,10 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
1876 ret = SSH_ERR_INVALID_FORMAT; 1879 ret = SSH_ERR_INVALID_FORMAT;
1877 goto out; 1880 goto out;
1878 } 1881 }
1882 if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
1883 ret = SSH_ERR_KEY_LENGTH;
1884 goto out;
1885 }
1879#ifdef DEBUG_PK 1886#ifdef DEBUG_PK
1880 RSA_print_fp(stderr, key->rsa, 8); 1887 RSA_print_fp(stderr, key->rsa, 8);
1881#endif 1888#endif
@@ -2643,6 +2650,10 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2643 (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || 2650 (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 ||
2644 (r = rsa_generate_additional_parameters(k->rsa)) != 0) 2651 (r = rsa_generate_additional_parameters(k->rsa)) != 0)
2645 goto out; 2652 goto out;
2653 if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
2654 r = SSH_ERR_KEY_LENGTH;
2655 goto out;
2656 }
2646 break; 2657 break;
2647 case KEY_RSA_CERT: 2658 case KEY_RSA_CERT:
2648 if ((r = sshkey_froms(buf, &k)) != 0 || 2659 if ((r = sshkey_froms(buf, &k)) != 0 ||
@@ -2653,6 +2664,10 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2653 (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || 2664 (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 ||
2654 (r = rsa_generate_additional_parameters(k->rsa)) != 0) 2665 (r = rsa_generate_additional_parameters(k->rsa)) != 0)
2655 goto out; 2666 goto out;
2667 if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
2668 r = SSH_ERR_KEY_LENGTH;
2669 goto out;
2670 }
2656 break; 2671 break;
2657#endif /* WITH_OPENSSL */ 2672#endif /* WITH_OPENSSL */
2658 case KEY_ED25519: 2673 case KEY_ED25519:
@@ -3427,6 +3442,10 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3427 r = SSH_ERR_LIBCRYPTO_ERROR; 3442 r = SSH_ERR_LIBCRYPTO_ERROR;
3428 goto out; 3443 goto out;
3429 } 3444 }
3445 if (BN_num_bits(prv->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
3446 r = SSH_ERR_KEY_LENGTH;
3447 goto out;
3448 }
3430 } else if (pk->type == EVP_PKEY_DSA && 3449 } else if (pk->type == EVP_PKEY_DSA &&
3431 (type == KEY_UNSPEC || type == KEY_DSA)) { 3450 (type == KEY_UNSPEC || type == KEY_DSA)) {
3432 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { 3451 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
diff --git a/sshkey.h b/sshkey.h
index fc1956605..b0b5b2749 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshkey.h,v 1.17 2017/05/03 21:08:09 naddy Exp $ */ 1/* $OpenBSD: sshkey.h,v 1.18 2017/05/07 23:15:59 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -46,7 +46,7 @@
46# define EC_POINT void 46# define EC_POINT void
47#endif /* WITH_OPENSSL */ 47#endif /* WITH_OPENSSL */
48 48
49#define SSH_RSA_MINIMUM_MODULUS_SIZE 768 49#define SSH_RSA_MINIMUM_MODULUS_SIZE 1024
50#define SSH_KEY_MAX_SIGN_DATA_SIZE (1 << 20) 50#define SSH_KEY_MAX_SIGN_DATA_SIZE (1 << 20)
51 51
52struct sshbuf; 52struct sshbuf;