diff options
author | djm@openbsd.org <djm@openbsd.org> | 2017-05-07 23:15:59 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2017-05-08 09:21:22 +1000 |
commit | bd636f40911094a39c2920bf87d2ec340533c152 (patch) | |
tree | 53c4c9655827d6433a26a510f46081dfc4b72b6d | |
parent | 70c1218fc45757a030285051eb4d209403f54785 (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.c | 24 | ||||
-rw-r--r-- | ssh-rsa.c | 10 | ||||
-rw-r--r-- | ssh.h | 5 | ||||
-rw-r--r-- | ssherr.c | 4 | ||||
-rw-r--r-- | ssherr.h | 3 | ||||
-rw-r--r-- | sshkey.c | 29 | ||||
-rw-r--r-- | sshkey.h | 4 |
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 | ||
@@ -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; |
@@ -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 |
@@ -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 | } |
@@ -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 */ |
82 | const char *ssh_err(int n); | 83 | const char *ssh_err(int n); |
@@ -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) { |
@@ -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 | ||
52 | struct sshbuf; | 52 | struct sshbuf; |