diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | sshd.c | 63 |
2 files changed, 53 insertions, 21 deletions
@@ -37,6 +37,15 @@ | |||
37 | - markus@cvs.openbsd.org 2001/02/23 15:34:53 | 37 | - markus@cvs.openbsd.org 2001/02/23 15:34:53 |
38 | [serverloop.c] | 38 | [serverloop.c] |
39 | debug2->3 | 39 | debug2->3 |
40 | - markus@cvs.openbsd.org 2001/02/23 18:15:13 | ||
41 | [sshd.c] | ||
42 | the random session key depends now on the session_key_int | ||
43 | sent by the 'attacker' | ||
44 | dig1 = md5(cookie|session_key_int); | ||
45 | dig2 = md5(dig1|cookie|session_key_int); | ||
46 | fake_session_key = dig1|dig2; | ||
47 | this change is caused by a mail from anakin@pobox.com | ||
48 | patch based on discussions with my german advisor niels@openbsd.org | ||
40 | 49 | ||
41 | 20010304 | 50 | 20010304 |
42 | - (bal) Remove make-ssh-known-hosts.1 since it's no longer valid. | 51 | - (bal) Remove make-ssh-known-hosts.1 since it's no longer valid. |
@@ -4229,4 +4238,4 @@ | |||
4229 | - Wrote replacements for strlcpy and mkdtemp | 4238 | - Wrote replacements for strlcpy and mkdtemp |
4230 | - Released 1.0pre1 | 4239 | - Released 1.0pre1 |
4231 | 4240 | ||
4232 | $Id: ChangeLog,v 1.863 2001/03/05 05:58:23 mouring Exp $ | 4241 | $Id: ChangeLog,v 1.864 2001/03/05 06:00:29 mouring Exp $ |
@@ -40,7 +40,7 @@ | |||
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include "includes.h" | 42 | #include "includes.h" |
43 | RCSID("$OpenBSD: sshd.c,v 1.168 2001/02/19 23:09:05 deraadt Exp $"); | 43 | RCSID("$OpenBSD: sshd.c,v 1.169 2001/02/23 18:15:13 markus Exp $"); |
44 | 44 | ||
45 | #include <openssl/dh.h> | 45 | #include <openssl/dh.h> |
46 | #include <openssl/bn.h> | 46 | #include <openssl/bn.h> |
@@ -154,6 +154,7 @@ struct { | |||
154 | Key **host_keys; /* all private host keys */ | 154 | Key **host_keys; /* all private host keys */ |
155 | int have_ssh1_key; | 155 | int have_ssh1_key; |
156 | int have_ssh2_key; | 156 | int have_ssh2_key; |
157 | u_char ssh1_cookie[SSH_SESSION_KEY_LENGTH]; | ||
157 | } sensitive_data; | 158 | } sensitive_data; |
158 | 159 | ||
159 | /* | 160 | /* |
@@ -274,13 +275,23 @@ grace_alarm_handler(int sig) | |||
274 | void | 275 | void |
275 | generate_empheral_server_key(void) | 276 | generate_empheral_server_key(void) |
276 | { | 277 | { |
278 | u_int32_t rand = 0; | ||
279 | int i; | ||
280 | |||
277 | log("Generating %s%d bit RSA key.", sensitive_data.server_key ? "new " : "", | 281 | log("Generating %s%d bit RSA key.", sensitive_data.server_key ? "new " : "", |
278 | options.server_key_bits); | 282 | options.server_key_bits); |
279 | if (sensitive_data.server_key != NULL) | 283 | if (sensitive_data.server_key != NULL) |
280 | key_free(sensitive_data.server_key); | 284 | key_free(sensitive_data.server_key); |
281 | sensitive_data.server_key = key_generate(KEY_RSA1, options.server_key_bits); | 285 | sensitive_data.server_key = key_generate(KEY_RSA1, options.server_key_bits); |
282 | arc4random_stir(); | ||
283 | log("RSA key generation complete."); | 286 | log("RSA key generation complete."); |
287 | |||
288 | for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { | ||
289 | if (i % 4 == 0) | ||
290 | rand = arc4random(); | ||
291 | sensitive_data.ssh1_cookie[i] = rand & 0xff; | ||
292 | rand >>= 8; | ||
293 | } | ||
294 | arc4random_stir(); | ||
284 | } | 295 | } |
285 | 296 | ||
286 | void | 297 | void |
@@ -438,6 +449,7 @@ destroy_sensitive_data(void) | |||
438 | } | 449 | } |
439 | } | 450 | } |
440 | sensitive_data.ssh1_host_key = NULL; | 451 | sensitive_data.ssh1_host_key = NULL; |
452 | memset(sensitive_data.ssh1_cookie, 0, SSH_SESSION_KEY_LENGTH); | ||
441 | } | 453 | } |
442 | Key * | 454 | Key * |
443 | load_private_key_autodetect(const char *filename) | 455 | load_private_key_autodetect(const char *filename) |
@@ -1338,14 +1350,6 @@ do_ssh1_kex(void) | |||
1338 | sensitive_data.server_key->rsa) < 0) | 1350 | sensitive_data.server_key->rsa) < 0) |
1339 | rsafail++; | 1351 | rsafail++; |
1340 | } | 1352 | } |
1341 | |||
1342 | compute_session_id(session_id, cookie, | ||
1343 | sensitive_data.ssh1_host_key->rsa->n, | ||
1344 | sensitive_data.server_key->rsa->n); | ||
1345 | |||
1346 | /* Destroy the private and public keys. They will no longer be needed. */ | ||
1347 | destroy_sensitive_data(); | ||
1348 | |||
1349 | /* | 1353 | /* |
1350 | * Extract session key from the decrypted integer. The key is in the | 1354 | * Extract session key from the decrypted integer. The key is in the |
1351 | * least significant 256 bits of the integer; the first byte of the | 1355 | * least significant 256 bits of the integer; the first byte of the |
@@ -1363,24 +1367,43 @@ do_ssh1_kex(void) | |||
1363 | memset(session_key, 0, sizeof(session_key)); | 1367 | memset(session_key, 0, sizeof(session_key)); |
1364 | BN_bn2bin(session_key_int, | 1368 | BN_bn2bin(session_key_int, |
1365 | session_key + sizeof(session_key) - len); | 1369 | session_key + sizeof(session_key) - len); |
1370 | |||
1371 | compute_session_id(session_id, cookie, | ||
1372 | sensitive_data.ssh1_host_key->rsa->n, | ||
1373 | sensitive_data.server_key->rsa->n); | ||
1374 | /* | ||
1375 | * Xor the first 16 bytes of the session key with the | ||
1376 | * session id. | ||
1377 | */ | ||
1378 | for (i = 0; i < 16; i++) | ||
1379 | session_key[i] ^= session_id[i]; | ||
1366 | } | 1380 | } |
1367 | } | 1381 | } |
1368 | if (rsafail) { | 1382 | if (rsafail) { |
1383 | int bytes = BN_num_bytes(session_key_int); | ||
1384 | char *buf = xmalloc(bytes); | ||
1385 | MD5_CTX md; | ||
1386 | |||
1369 | log("do_connection: generating a fake encryption key"); | 1387 | log("do_connection: generating a fake encryption key"); |
1370 | for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { | 1388 | BN_bn2bin(session_key_int, buf); |
1371 | if (i % 4 == 0) | 1389 | MD5_Init(&md); |
1372 | rand = arc4random(); | 1390 | MD5_Update(&md, buf, bytes); |
1373 | session_key[i] = rand & 0xff; | 1391 | MD5_Update(&md, sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); |
1374 | rand >>= 8; | 1392 | MD5_Final(session_key, &md); |
1375 | } | 1393 | MD5_Init(&md); |
1394 | MD5_Update(&md, session_key, 16); | ||
1395 | MD5_Update(&md, buf, bytes); | ||
1396 | MD5_Update(&md, sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); | ||
1397 | MD5_Final(session_key + 16, &md); | ||
1398 | memset(buf, 0, bytes); | ||
1399 | xfree(buf); | ||
1376 | } | 1400 | } |
1401 | /* Destroy the private and public keys. They will no longer be needed. */ | ||
1402 | destroy_sensitive_data(); | ||
1403 | |||
1377 | /* Destroy the decrypted integer. It is no longer needed. */ | 1404 | /* Destroy the decrypted integer. It is no longer needed. */ |
1378 | BN_clear_free(session_key_int); | 1405 | BN_clear_free(session_key_int); |
1379 | 1406 | ||
1380 | /* Xor the first 16 bytes of the session key with the session id. */ | ||
1381 | for (i = 0; i < 16; i++) | ||
1382 | session_key[i] ^= session_id[i]; | ||
1383 | |||
1384 | /* Set the session key. From this on all communications will be encrypted. */ | 1407 | /* Set the session key. From this on all communications will be encrypted. */ |
1385 | packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type); | 1408 | packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type); |
1386 | 1409 | ||