diff options
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 57 |
1 files changed, 38 insertions, 19 deletions
@@ -40,7 +40,7 @@ | |||
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include "includes.h" | 42 | #include "includes.h" |
43 | RCSID("$OpenBSD: sshd.c,v 1.158 2001/01/28 10:37:26 markus Exp $"); | 43 | RCSID("$OpenBSD: sshd.c,v 1.159 2001/01/29 19:47:31 markus Exp $"); |
44 | 44 | ||
45 | #include <openssl/dh.h> | 45 | #include <openssl/dh.h> |
46 | #include <openssl/bn.h> | 46 | #include <openssl/bn.h> |
@@ -1186,6 +1186,7 @@ do_ssh1_kex(void) | |||
1186 | { | 1186 | { |
1187 | int i, len; | 1187 | int i, len; |
1188 | int plen, slen; | 1188 | int plen, slen; |
1189 | int rsafail = 0; | ||
1189 | BIGNUM *session_key_int; | 1190 | BIGNUM *session_key_int; |
1190 | u_char session_key[SSH_SESSION_KEY_LENGTH]; | 1191 | u_char session_key[SSH_SESSION_KEY_LENGTH]; |
1191 | u_char cookie[8]; | 1192 | u_char cookie[8]; |
@@ -1296,7 +1297,7 @@ do_ssh1_kex(void) | |||
1296 | * with larger modulus first). | 1297 | * with larger modulus first). |
1297 | */ | 1298 | */ |
1298 | if (BN_cmp(sensitive_data.server_key->rsa->n, sensitive_data.ssh1_host_key->rsa->n) > 0) { | 1299 | if (BN_cmp(sensitive_data.server_key->rsa->n, sensitive_data.ssh1_host_key->rsa->n) > 0) { |
1299 | /* Private key has bigger modulus. */ | 1300 | /* Server key has bigger modulus. */ |
1300 | if (BN_num_bits(sensitive_data.server_key->rsa->n) < | 1301 | if (BN_num_bits(sensitive_data.server_key->rsa->n) < |
1301 | BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { | 1302 | BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { |
1302 | fatal("do_connection: %s: server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", | 1303 | fatal("do_connection: %s: server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", |
@@ -1305,10 +1306,12 @@ do_ssh1_kex(void) | |||
1305 | BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), | 1306 | BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), |
1306 | SSH_KEY_BITS_RESERVED); | 1307 | SSH_KEY_BITS_RESERVED); |
1307 | } | 1308 | } |
1308 | rsa_private_decrypt(session_key_int, session_key_int, | 1309 | if (rsa_private_decrypt(session_key_int, session_key_int, |
1309 | sensitive_data.server_key->rsa); | 1310 | sensitive_data.server_key->rsa) <= 0) |
1310 | rsa_private_decrypt(session_key_int, session_key_int, | 1311 | rsafail++; |
1311 | sensitive_data.ssh1_host_key->rsa); | 1312 | if (rsa_private_decrypt(session_key_int, session_key_int, |
1313 | sensitive_data.ssh1_host_key->rsa) <= 0) | ||
1314 | rsafail++; | ||
1312 | } else { | 1315 | } else { |
1313 | /* Host key has bigger modulus (or they are equal). */ | 1316 | /* Host key has bigger modulus (or they are equal). */ |
1314 | if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) < | 1317 | if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) < |
@@ -1319,10 +1322,12 @@ do_ssh1_kex(void) | |||
1319 | BN_num_bits(sensitive_data.server_key->rsa->n), | 1322 | BN_num_bits(sensitive_data.server_key->rsa->n), |
1320 | SSH_KEY_BITS_RESERVED); | 1323 | SSH_KEY_BITS_RESERVED); |
1321 | } | 1324 | } |
1322 | rsa_private_decrypt(session_key_int, session_key_int, | 1325 | if (rsa_private_decrypt(session_key_int, session_key_int, |
1323 | sensitive_data.ssh1_host_key->rsa); | 1326 | sensitive_data.ssh1_host_key->rsa) < 0) |
1324 | rsa_private_decrypt(session_key_int, session_key_int, | 1327 | rsafail++; |
1325 | sensitive_data.server_key->rsa); | 1328 | if (rsa_private_decrypt(session_key_int, session_key_int, |
1329 | sensitive_data.server_key->rsa) < 0) | ||
1330 | rsafail++; | ||
1326 | } | 1331 | } |
1327 | 1332 | ||
1328 | compute_session_id(session_id, cookie, | 1333 | compute_session_id(session_id, cookie, |
@@ -1337,15 +1342,29 @@ do_ssh1_kex(void) | |||
1337 | * least significant 256 bits of the integer; the first byte of the | 1342 | * least significant 256 bits of the integer; the first byte of the |
1338 | * key is in the highest bits. | 1343 | * key is in the highest bits. |
1339 | */ | 1344 | */ |
1340 | BN_mask_bits(session_key_int, sizeof(session_key) * 8); | 1345 | if (!rsafail) { |
1341 | len = BN_num_bytes(session_key_int); | 1346 | BN_mask_bits(session_key_int, sizeof(session_key) * 8); |
1342 | if (len < 0 || len > sizeof(session_key)) | 1347 | len = BN_num_bytes(session_key_int); |
1343 | fatal("do_connection: bad len from %s: session_key_int %d > sizeof(session_key) %d", | 1348 | if (len < 0 || len > sizeof(session_key)) { |
1344 | get_remote_ipaddr(), | 1349 | error("do_connection: bad session key len from %s: " |
1345 | len, sizeof(session_key)); | 1350 | "session_key_int %d > sizeof(session_key) %d", |
1346 | memset(session_key, 0, sizeof(session_key)); | 1351 | get_remote_ipaddr(), len, sizeof(session_key)); |
1347 | BN_bn2bin(session_key_int, session_key + sizeof(session_key) - len); | 1352 | rsafail++; |
1348 | 1353 | } else { | |
1354 | memset(session_key, 0, sizeof(session_key)); | ||
1355 | BN_bn2bin(session_key_int, | ||
1356 | session_key + sizeof(session_key) - len); | ||
1357 | } | ||
1358 | } | ||
1359 | if (rsafail) { | ||
1360 | log("do_connection: generating a fake encryption key"); | ||
1361 | for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { | ||
1362 | if (i % 4 == 0) | ||
1363 | rand = arc4random(); | ||
1364 | session_key[i] = rand & 0xff; | ||
1365 | rand >>= 8; | ||
1366 | } | ||
1367 | } | ||
1349 | /* Destroy the decrypted integer. It is no longer needed. */ | 1368 | /* Destroy the decrypted integer. It is no longer needed. */ |
1350 | BN_clear_free(session_key_int); | 1369 | BN_clear_free(session_key_int); |
1351 | 1370 | ||